1.嵌套时如何使循环处理更快。从(a)到(zzzzz)处理1个字符需要30秒
2.如何使此代码能够设置范围,例如开始2位数并以4位数结束。
3.为什么这段代码显示编码命令,这就是为什么我从命令
中输入character @ atSample.bat
@echo off
setlocal EnableDelayedExpansion
set "loop2=IN (0,1,36) DO @("
set "n0="
set "n1=a"
set "n2=b"
set "n3=c"
set "n4=d"
set "n5=e"
set "n6=f"
set "n7=g"
set "n8=h"
set "n9=i"
set "n10=j"
set "n11=k"
set "n12=l"
set "n13=m"
set "n14=n"
set "n15=o"
set "n16=p"
set "n17=q"
set "n18=r"
set "n19=s"
set "n20=t"
set "n21=u"
set "n22=v"
set "n23=w"
set "n24=x"
set "n25=y"
set "n26=z"
set "n27=1"
set "n28=2"
set "n29=3"
set "n30=4"
set "n31=5"
set "n32=6"
set "n33=7"
set "n34=8"
set "n35=9"
set "n36=0"
@FOR /L %%a %loop2%
@call :prc %%a
@FOR /L %%b %loop2%
@call :prc %%a %%b
@FOR /L %%c %loop2%
@call :prc %%a %%b %%c
@FOR /L %%d %loop2%
@call :prc %%a %%b %%c %%d
@FOR /L %%e %loop2%
@call :prc %%a %%b %%c %%d %%e
)
)
)
)
)
)
@pause
:prc
::@cls
@title %1 %2 %3 = !n%1!!n%2!!n%3!
@set "data=!n%1!!n%2!!n%3!!n%4!!n%5!"
@if not defined data goto end
@echo.
@echo %data% >> data.txt
@echo.
@:end
@goto :eof
`
答案 0 :(得分:5)
我弄清楚为什么ECHO OFF有时似乎不起作用 - 当你打印两位数的字符串时,你最终会到达" on",这会产生echo on
。很明显为什么这是一个问题!
你应该使用安全形式的ECHO,其中最好的是echo(
- 它看起来很奇怪,但它确实有效。
考虑到优化的性能,Aacini的解决方案是第一个出现在我脑海中的想法。但是如果你真的想要最好的性能,你应该完全消除循环中的环境变量扩展。这可以通过切换到直接迭代符号(数字)的简单FOR来轻松完成。
您声明要控制每个字符串打印的最小和最大位数。这可以通过添加一些IF语句轻松完成。但IF需要时间来执行。最好将整个嵌套循环集合动态地构建为单个代码串。这样,您的主循环总是被优化,以尽可能少地完成工作。
这是我的优化版本。我在你的原始代码中随意将最大位数限制为5。虽然最终代码必须符合~8192个字符,但可以很容易地扩展。理论上支持最多68位的字符串,但如果该程序完成时人类仍然存在于这个星球上将是非常了不起的!地狱,到那时地球可能已经很久了!
:: %1 = min number of digits, between 1 and 5. Default = 1
:: %2 = max number of digits, between 1 and 5. Default = 5
::
@echo off
setlocal enableDelayedExpansion
:: Configuration
set /a "min=1, max=5"
if "%~1" neq "" set "min=%~1"
if "%~2" neq "" set "max=%~2"
if %min% lss 1 set min=1
if %max% lss 1 set min=1
if %min% gtr 5 set min=5
if %max% gtr 5 set max=5
:: Define symbols to be iterated by simple FOR
:: Use of simple FOR improves performance by eliminating environment variable
:: dereferencing within main loops.
set "chars=a b c d e f g h i j k l m n o p q r s t u v w x y z 1 2 3 4 5 6 7 8 9 0"
:: Dynamically build code as a "macro"
:: This enables configuration of number of digits printed, yet improves performance
:: by avoiding IF within main loops.
set "code="
set "digits="
for /l %%N in (1 1 %max%) do (
set "code=!code!for %%%%N in (%chars%) do "
set "digits=!digits!%%%%N"
if %%N geq %min% (
set "code=!code!echo(!digits!"
if %%N lss %max% set "code=!code!&"
)
)
:: Show the resultant code
echo !code!
:: Execute the code
>data.txt (%code%)
使用最小值1和最大值4,在我的机器上完成需要35秒。将max增加到5将至少需要21分钟。相比之下,从Aacini代码中消除内循环,修复ECHO ON问题,在我的机器上生成长度为1到4的所有字符串需要85秒。
下面是由min = 2,max = 3生成的代码,只需1秒即可完成。我故意使用引用块而不是代码块来避免过度的水平滚动。
for%1 in(abcdefghijklmnopqrstu vwxyz 1 2 3 4 5 6 7 8 9 0)for%2 in(abcdefghijklmnopqrstu vwxyz 1 2 3 4 5 6 7 8 9 0)do echo(%1%2& for% 3 in(abcdefghijklmnopqrstu vwxyz 1 2 3 4 5 6 7 8 9 0)做回声(%1%2%3
请注意,以上是展开%code%
后的代码,因此%1
表示FOR变量,而不是第一个批处理脚本参数。
答案 1 :(得分:3)
除LotPings' answer中给出的建议外,还有两种构造特别慢:
call
命令。如果你想要速度,请避免调用子程序。您可以使用宏(与原始的loop2
变量一样,但使用完整的命令)。>>
重定向。此表单在每次使用时都执行以下步骤:1 - 打开文件。 2寻找文件的结尾。 3 - 附加数据。 4 - 关闭文件。 更快使用唯一的>
重定向,使文件始终保持打开状态,直到流程结束。我还修改了你的代码,以使其更具可读性:
@echo off
setlocal EnableDelayedExpansion
set "i=0"
for %%a in (a b c d e f g h i j k l m n o p q r s t u v w x y z 1 2 3 4 5 6 7 8 9 0) do (
set /A i+=1
set "n!i!=%%a"
)
set "range2=1,1,36"
(FOR /L %%a IN (%range2%) DO (
echo !n%%a!
FOR /L %%b IN (%range2%) DO (
echo !n%%a!!n%%b!
FOR /L %%c IN (%range2%) DO (
echo !n%%a!!n%%b!!n%%c!
FOR /L %%d IN (%range2%) DO (
echo !n%%a!!n%%b!!n%%c!!n%%d!
FOR /L %%e IN (%range2%) DO (
echo !n%%a!!n%%b!!n%%c!!n%%d!!n%%e!
)
)
)
)
)) > data.txt
答案 2 :(得分:2)
如何在嵌套时更快地进行循环处理? 删除所有不必要的命令。
如何使此代码能够设置范围?
采用不同的递归方法构建字符串,
看起来像是在做差异。数字基数。
BTW 36 power 5是60.466.176,通常你以
开头
数字0后跟九个像十六进制0-9abcdef
为什么此代码显示编码命令?
Echo off
禁用文件输出,只需写入控制台和 从第一个字母开始。
@echo off & setlocal EnableDelayedExpansion
set "n= abcdefghijklmnopqrstuvwxyz1234567890"
for /l %%n in (1,1,36) do set "n%%n=!n:~%%n,1!"
set "n="
set "loop2=in (1,1,36) DO ("
FOR /L %%a %loop2%
call :prc %%a
FOR /L %%b %loop2%
call :prc %%a %%b
FOR /L %%c %loop2%
call :prc %%a %%b %%c
FOR /L %%d %loop2%
call :prc %%a %%b %%c %%d
FOR /L %%e %loop2%
call :prc %%a %%b %%c %%d %%e
)
Pause
)
)
)
)
pause
Goto :Eof
:prc
set "data=!n%1!!n%2!!n%3!!n%4!!n%5!"
echo %data% &Rem>> data.txt
goto :eof