Board logo

标题: [数值计算] [出题]批处理求6个字符所有的组合可能 [打印本页]

作者: youxi01    时间: 2008-4-2 17:49     标题: [出题]批处理求6个字符所有的组合可能

现有 6个字符:1、2、3、a、b、c,求所有的组合可能(不允许出现重复字符)

如:123abc
作者: 随风    时间: 2008-4-2 18:55

笨办法倒是有一个
  用for /l %%a in (123456 1 666666) do ........
    再对重复的数字进行处理。再把456替换成abc
作者: foxJL    时间: 2008-4-2 19:09

不知道正不正确.
  1. @echo off
  2. for %%a in (1 2 3 a b c) do (
  3. for %%b in (2 3 a b c 1) do (
  4. for %%c in (3 a b c 1 2) do (
  5. for %%d in (a b c 1 2 3) do (
  6. for %%e in (b c 1 2 3 a) do (
  7. for %%f in (c 1 2 3 a b) do (
  8. echo %%a %%b %%c %%d %%e %%f
  9. set /a n+=1
  10. call title %%n%%组
  11. )
  12. )
  13. )
  14. )
  15. )
  16. )
  17. pause
复制代码

作者: youxi01    时间: 2008-4-2 20:47

要求不出现重复字符哦
比如,不能出现:aabc12的形式,这里aa重复
作者: youxi01    时间: 2008-4-2 20:49

如果是3F的情况,似乎不必打乱abc123的顺序吧?
作者: 随风    时间: 2008-4-2 22:40

用笨办法得到了结果
共组合了46656 次   有  720 个结果。
可怜我的批处理,在我的电脑上足足跑了一个小时。。。
作者: youxi01    时间: 2008-4-2 23:49     标题: 回复 2楼 的帖子

你这个思路,那最后的数值可以不是:666666,而应该是654321了,呵呵。
作者: 随风    时间: 2008-4-3 01:02

呵呵,不是按我2楼的思路,是按3楼的思路。
:
  1. @echo off&color 1f&set "n=0"
  2. echo 正在排列,请耐心等候。。。
  3. echo\&echo 开始时间 %time%
  4. set t=%time%
  5. echo.
  6. set var=1 2 3 a b c
  7. for %%a in (%var%) do (
  8.   for %%b in (%var%) do (
  9.   for %%c in (%var%) do (
  10.   for %%d in (%var%) do (
  11.   for %%e in (%var%) do (
  12.   for %%f in (%var%) do (
  13.   set /a w+=1
  14.   call title 排列次数 %%w%% 次, 排列结果 %%n%% 个
  15.   setlocal enabledelayedexpansion
  16.   set lis=%%a %%b %%c %%d %%e %%f
  17.   for %%i in (!lis!) do set /a _%%i+=1
  18.   for /f "tokens=2 delims==" %%j in ('set _') do if %%j geq 2 set flag=a
  19.   if not defined flag (
  20.     >>pai.txt echo !lis!
  21.     echo !lis!
  22.     endlocal&set /a n+=1
  23.   ) else endlocal
  24. ))))))
  25. >>pai.txt echo 排列次数 %w% 次, 排列结果 %n% 个
  26. >>pai.txt echo 开始时间 %t%
  27. >>pai.txt echo 结束时间 %time%
  28. pause
复制代码

作者: 随风    时间: 2008-4-3 18:27

哈哈,2楼的思路快多了,只用了10分钟。
:
  1. @echo off&setlocal enabledelayedexpansion
  2. echo 正在排列,请耐心等候。。。
  3. echo\&echo 开始时间 %time%
  4. set t=%time%
  5. for /l %%i in (123456 1 654321) do (
  6.   for /l %%a in (1 1 6) do set "%%a="
  7.   set flag=&set var=%%i
  8.   set num=!var:~0,1! !var:~1,1! !var:~2,1! !var:~3,1! !var:~4,1! !var:~5,1!
  9.   for /l %%a in (1 1 6) do set var=!var:%%a=!
  10.      if not defined var (
  11.    for %%a in (!num!) do (
  12.      if not defined %%a (set %%a=a) else set flag=a
  13.    )
  14.    if not defined flag (
  15.     set num=!num:4=a!
  16.     set num=!num:5=b!
  17.     set num=!num:6=c!
  18.     echo !num!
  19.     set /a n+=1
  20.     title 第 !n! 个组合
  21. )))
  22. echo 共有 !n!个组合
  23. echo 结束时间 %time%
  24. pause
复制代码

作者: youxi01    时间: 2008-4-3 18:41

上午上班的时候写了一段 排除法的代码(根据排列组合原理),运行速度还算比较快,10S内完成,但是结果不正确(因为根据排列组合的知识,无重复数字的组合应该是 720 种,但计算出来的结果却是 2160,变为3倍),又找不出原因,所以就没有公布了。

算法类3F
作者: 小竹    时间: 2008-4-3 19:36

  1. @echo off
  2. set starttime=%time%
  3. setlocal enabledelayedexpansion
  4. set var1=1 2 3 a b c
  5. for %%i in (!var1!) do (
  6. set var2=!var1:%%i=!
  7. for %%j in (!var2!) do (
  8.   set var3=!var2:%%j=!
  9.   for %%k in (!var3!) do (
  10.    set var4=!var3:%%k=!
  11.    for %%l in (!var4!) do (
  12.     set var5=!var4:%%l=!
  13.     for %%m in (!var5!) do (
  14.      set var6=!var5:%%m=!
  15.       for %%n in (!var6!) do (
  16.       echo %%i%%j%%k%%l%%m%%n
  17.       set /a flag+=1
  18.       )
  19.     )
  20.    )
  21.   )
  22. )
  23. )
  24. set endtime=%time%
  25. echo 共有%flag%个组合
  26. echo 开始时间为 %starttime%
  27. echo 结束时间为 %endtime%
  28. pause
复制代码

不到5s。

[ 本帖最后由 小竹 于 2008-4-3 21:24 编辑 ]
作者: 随风    时间: 2008-4-3 19:49

赞一个,除了加分不知道说什么好了
至于排列效果
echo %%i%%j%%k%%l%%m!var6: =!
就可以了。

[ 本帖最后由 随风 于 2008-4-3 20:00 编辑 ]
作者: plp626    时间: 2008-4-3 21:08

123abc
  23abc
     3abc
       abc
          bc
             c
作者: youxi01    时间: 2008-4-3 21:45

呵呵,11F的代码和我当初的代码很相似了。
不过当初这里:
     set var6=!var5:%%m=!
      for %%n in (!var6!) do (
      echo %%i%%j%%k%%l%%m%%n
      set /a flag+=1
      )
我就省略了,才6个数字,最后一个循环没什么意义了。
不过,我不明白当初的运行结果竟然是 2160,不知道为什么??
作者: 随风    时间: 2008-4-3 21:57

呵呵,把你的代码发来看看啊。
他本来没有最后一个for的,不知为何要加一个,直接echo %%i%%j%%k%%l%%m!var6: =! 不是挺好的吗。

[ 本帖最后由 随风 于 2008-4-3 21:58 编辑 ]
作者: 小竹    时间: 2008-4-3 22:14     标题: 回复 15楼 的帖子

呵呵,既然循环了,就循环到底吧,反正结果都差不多。
作者: heaton    时间: 2008-4-16 14:34

如果有相同的字符就出错了,
作者: 523066680    时间: 2009-7-27 21:44

来个递归的
Call 的第二个参数是排列的字符,暂时不支持排列内带重复的字符。

  1. @echo off&setlocal enabledelayedexpansion
  2. call :func "0" "" "123abc"
  3. pause
  4. :func
  5. if %3=="" (set /a na=%~1+1
  6.            echo,%~2
  7.            goto :eof)
  8. set na=0
  9. :loop
  10.       set str=%~3
  11.       set /a nb=na+1
  12.       call :func "%na%" "%~2!str:~%na%,1!" "!str:~0,%na%!!str:~%nb%!"
  13.       set str=%~3
  14. if not "!str:~%na%!"=="" goto :loop
  15. set /a na=%~1+1
复制代码

作者: stuqx    时间: 2009-7-28 15:03

一个比一个精湛   连递归都用上了




欢迎光临 批处理之家 (http://bbs.bathome.net/) Powered by Discuz! 7.2