[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖
来一个穷举法
  1. @echo off
  2. setlocal enableDelayedExpansion
  3. set "arr=51, 8, 13, 2, 52, 61, 37, 85, 19, 11, 7, 62, 22, 38, 79"
  4. set /a range1=102, range2=105
  5. for %%a in (%arr%) do set /a num+=1 & set a[!num!]=%%a
  6. rem 冒泡排序
  7. for /l %%i in (1 1 %num%) do (
  8.     set /a start = %%i + 1
  9.     for /l %%j in (!start! 1 %num%) do if !a[%%i]! gtr !a[%%j]! (
  10.         set tmp=!a[%%i]!
  11.         set a[%%i]=!a[%%j]!
  12.         set a[%%j]=!tmp!
  13.     )
  14. )
  15. for /l %%a in (1 1 %num%) do (
  16.     set /a min=0, max=0
  17.     for /l %%i in (1 1 %%a) do set /a min+=a[%%i], n=num-%%i+1&set /a max+=a[!n!]
  18.     if !min! leq %range2% if !max! geq %range1% (
  19.         rem echo %%a:[!min!,!max!]
  20.         call :Arrangement  %%a %num%
  21.     )
  22. )
  23. pause&exit/b
  24. rem 获取排列
  25. :Arrangement [num] [len]
  26. setlocal enableDelayedExpansion
  27. set /a num=%1, len=%2
  28. for /l %%a in (1 1 %num%) do (
  29.     if 1==%%a (set start=1&set "setstart=set start=1&") else (set /a start=%%a-1&set start=%%!start!&set "setstart=set /a start=!start!+1&")
  30.     set "do=!do! !setstart! for /l %%%%a in (^!start^!,1,%len%) do "
  31.     set "exp=!exp!,^!a[%%%%a]^!"
  32. )
  33. %do% (
  34.     set /a prior=sum, sum=0
  35.     if !prior! leq %range2% (
  36.         for %%a in (%exp%) do set /a sum+=%%a
  37.         if !sum! geq %range1% if !sum! leq %range2% echo%exp:,=+%=!sum!
  38.     )
  39. )
  40. endlocal
  41. goto :eof
复制代码

TOP

思维稍乱,重新整理了一下
  1. @echo off
  2. set "arr=51, 8, 13, 2, 52, 61, 37, 85, 19, 11, 7, 62, 22, 38, 79,  1,2,3"
  3. set /a range1=102, range2=105
  4. :main
  5. setlocal enableDelayedExpansion
  6. for %%a in (%arr%) do set /a num+=1 & set a[!num!]=%%a
  7. if %num% gtr 20 echo Are you killing me?&pause&exit /b %num%
  8. rem 冒泡排序
  9. for /l %%i in (1 1 %num%) do (
  10.     set /a start = %%i + 1
  11.     for /l %%j in (!start! 1 %num%) do if !a[%%i]! gtr !a[%%j]! (
  12.         set tmp=!a[%%i]!
  13.         set a[%%i]=!a[%%j]!
  14.         set a[%%j]=!tmp!
  15.     )
  16. )
  17. for /l %%a in (1 1 %num%) do (
  18.     set /a min=0, max=0
  19.     for /l %%i in (1 1 %%a) do set /a min+=a[%%i], n=num-%%i+1&set /a max+=a[!n!]
  20.     if !min! leq %range2% if !max! geq %range1% (
  21.         rem echo %%a:[!min!,!max!]
  22.         call :Combination  %%a %num%
  23.     )
  24. )
  25. pause
  26. endlocal&exit/b
  27. rem 获取组合
  28. :Combination [num] [len]
  29. %static% set letters=[abcdefghijklmnopqrstuvwxyz]
  30. setlocal enableDelayedExpansion
  31. set /a num=%1, len=%2
  32. for /l %%a in (1 1 %num%) do (
  33.     set var=!letters:~%%a,1!
  34.     if 1==%%a (
  35.         set "set_start=set start=1"
  36.     ) else (
  37.         set /a base=%%a-1
  38.         for %%i in (!base!) do set base=!letters:~%%i,1!
  39.         set "set_start=set /a start=%%!base!+1"
  40.     )
  41.     set "do=!do! !set_start! & for /l %%!var! in (^!start^!,1,%len%) do "
  42.     set "exp=!exp!,^!a[%%!var!]^!"
  43. )
  44. %do% (
  45.     set /a prior=sum, sum=0
  46.     if !prior! leq %range2% (
  47.         for %%a in (%exp%) do set /a sum+=%%a
  48.         if !sum! geq %range1% if !sum! leq %range2% echo%exp:,=+%=!sum!
  49.     )
  50. )
  51. endlocal
  52. goto :eof
复制代码

TOP

我知道是这个意思。
set "arr=51, 8, 13, 2, 52, 61, 37, 85, 19, 11, 7, 62, 22, 38, 79,  1,2,3"
后面故意加了个重复数字

TOP

思维形成定势了,果然有纰漏。稍作改造如下:
  1. @echo off
  2. set "arr=51, 8, 13, 2, 52, 61, 37, 85, 19, 11, 7, 62, 22, 38, 79"
  3. set /a min=102, max=105
  4. :main
  5. setlocal enableDelayedExpansion
  6. %const% set MAXNUM=20
  7. for %%a in (%arr%) do set /a num+=1 & set a[!num!]=%%a
  8. if %num% gtr %MAXNUM% echo Are you kidding me?&pause&exit /b %num%
  9. rem 冒泡排序
  10. for /l %%i in (1 1 %num%) do (
  11.     set /a start = %%i + 1
  12.     for /l %%j in (!start! 1 %num%) do if !a[%%i]! gtr !a[%%j]! (
  13.         set tmp=!a[%%i]!
  14.         set a[%%i]=!a[%%j]!
  15.         set a[%%j]=!tmp!
  16.     )
  17. )
  18. rem 为枚举组合数生成for嵌套语句
  19. set letters=[abcdefghijklmnopqrstuvwxyz]
  20. for /l %%a in (1 1 %MAXNUM%) do (
  21.     set var=!letters:~%%a,1!
  22.     if 1==%%a (
  23.         set "set_start=set /a start=00+1"
  24.     ) else (
  25.         set /a base=%%a-1
  26.         for %%i in (!base!) do set base=!letters:~%%i,1!
  27.         set "set_start=set /a start=%%!base!+1"
  28.     )
  29.     set "do=!do!!set_start! & for /l %%!var! in (^!start^!,1,^!num^!) do "
  30.     set "exp=!exp!,^!a[%%!var!]^!"
  31. )
  32. rem echo !do!
  33. rem echo !exp!
  34. rem pause
  35. for /l %%a in (1 1 %num%) do (
  36.     set /a minsum=0, maxsum=0
  37.     for /l %%i in (1 1 %%a) do set /a minsum+=a[%%i], n=num-%%i+1&set /a maxsum+=a[!n!]
  38.     rem echo %%a:[!minsum!,!maxsum!]
  39.     if !minsum! leq %max% if !maxsum! geq %min% (
  40.         set /a do_len=54*%%a, exp_len=8*%%a
  41.         call:enum
  42.     )
  43. )
  44. pause
  45. endlocal&exit/b
  46. :enum
  47. setlocal enableDelayedExpansion
  48. set do=!do:~0,%do_len%!
  49. set exp=!exp:~0,%exp_len%!
  50. %do% (
  51.     set /a sum=0%exp:,=+%
  52.     if !sum! geq %min% if !sum! leq %max% echo%exp:,=+%=!sum!
  53. )
  54. endlocal
  55. goto :eof
复制代码

TOP

思路比较普通:先排序,分别从数组中取N个数(1≤N≤num)进行组合(先简单判断是否需要取组合数),再将组合数的和与目标比较。取组合数用的是for嵌套循环(利用bat预处理机制),echo !do!就知道展开后是什么了。

之前形成思维定势,老想着因为数组经过排序,所以如果前一组组合数的和大于max,后面就不用比较了,也即下面的当prior(sum)小于max时才比较:
    set /a prior=sum, sum=0
    if !prior! leq %max% (
        for %%a in (%exp%) do set /a sum+=%%a
        if !sum! geq %min% if !sum! leq %max% echo%exp:,=+%=!sum!
    )
还有逻辑问题,完全是废代码。

TOP

递归里面用循环,循环体里面又递归调用,这个递归是很多层的。(这种方法很少用,要死很多脑细胞的)
楼上估计是把递归函数第一个语句还要循环给忘了:
for /l %%i in (%i% 1 %N%) do (

TOP

“调用函数会得到12,123,1234,12345,123456,1234567,12345678。此时跳出函数”
递归函数也有for啊,这个for取第一个值时,通过递归,就得到了12,123,1234,12345,123456,1234567,12345678,还远远没到跳出的时候。每次递归都要带来一次循环,每个循环体里面又要递归……

TOP

返回列表