[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖
回复 1# plp626

楼主的算法确实精简高效,把数学计算用到了极致。但这两天在学习时发现,该代码存在以下问题:
1、使用for /l (128 64 32...)时,判断某数为空后折半,需要把括号中的数减一后再判断,就如
if "!a:~127,1!" neq ""  set /a "len+=%%a",而不是if "!a:~%%a,1!" neq ""  set /a "len+=%%a"。用这种算法,固然可以在全部计算后最终加1得到正确长度,但是毕竟原代码结果不正确。

2、第9句的set/a "len+=0x!s:~16,1!",应该是set/a "len+=0x!s:~15,1!"

说的不对的地方,请斧正。

我的代码如下:
  1. @echo off
  2. set "var=1234567890abcdefghijklmnopqrstuv12345678901234567890abcdefghijklmnopqrstuv12345678901234567890abcdefghijklmnopqrstuv12345678901"
  3. call :Len var,n
  4. echo 长度为%n%
  5. pause&exit
  6. :Len
  7. Setlocal enabledelayedexpansion
  8. set "s=!%1!"
  9. for %%a in (512 256 128 64 32 16) do (
  10. set/a "m1=%%a-1" &call set "b1=%%s:~!m1!,1%%"
  11. if "!b1!" neq "" (
  12. set/a "len+=%%a" &set "s=!s:~%%a!"
  13. if "!s!"=="" goto ok )
  14. )
  15. set "s=!s!fedcba9876543210" &set/a "len+=0x!s:~15,1!"
  16. :ok
  17. endlocal&set/a "%2=%len%"&goto:eof
  18. pause
复制代码

TOP

回复 22# Batcher
  1. @echo off
  2. set a="1234567890abcdef"
  3. call :Len a n
  4. echo 长度为%n%
  5. pause&exit
  6. :Len
  7. setlocal enabledelayedexpansion
  8. set "$=!%1!#"
  9. set len=&for %%a in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1)do if !$:~%%a^,1!. NEQ . set/a len+=%%a&set $=!$:~%%a!
  10. endlocal&If %2. neq . (set/a%2=%len%)else echo %len%
复制代码
执行结果:长度为18
实际上应该是16

TOP

本帖最后由 踏沙行 于 2018-8-1 15:40 编辑

回复 24# Batcher
谢谢,是我写的有问题。
修正后再测试,代码如下:
  1. @echo off
  2. set "a=1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef"
  3. rem a的长度为64
  4. call :Ten a n
  5. echo 长度为%n%
  6. pause&exit
  7. :Ten
  8. setlocal enabledelayedexpansion
  9. set "$=!%1!#"
  10. set "len="
  11. for %%a in (64 32 16 8 4 2 1) do (
  12. if !$:~%%a^,1!. NEQ . set/a len+=%%a&set $=!$:~%%a!
  13. set/a "T=T+1"&echo.第!T!次判断
  14. )
  15. endlocal&If %2. neq . (set/a%2=%len%)else echo %len%
复制代码
运行结果为:
第1次判断
第2次判断
第3次判断
第4次判断
第5次判断
第6次判断
第7次判断
长度为64
请按任意键继续. . .

【问题】本来字符长度为64,可以一次判断出结果。但是因为使用了set "$=!%1!#",让计算次数增加了6次
而且,对于if !$:~%%a^,1!. NEQ .这样的判断,如果字符串中存在有.(点号),也会影响正常判断吧

TOP

回复 26# Batcher
  1. @echo off
  2. set "a=1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef"
  3. call :Ten a n
  4. echo 长度为%n%
  5. pause&exit
  6. :Ten
  7. setlocal enabledelayedexpansion
  8. set "$=!%1!#"
  9. set "len="&for %%a in (4096 2048 1024 256 128 64 32 16 8 4 2 1) do (if "!$:~%%a,1!" NEQ "" set/a len+=%%a&set "$=!$:~%%a!" &if "!$:~1!"=="" goto ok)
  10. set "s=!s!fedcba9876543210" &set/a "len+=0x!s:~16,1!"
  11. :ok
  12. endlocal&set/a "%2=%len%"&goto:eof
  13. pause
复制代码
增加 if "!$:~1!"=="" goto ok,可以在刚好够2分时,及时跳出循环。

TOP

返回列表