找回密码
 注册
搜索
[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
查看: 92449|回复: 32

[ 新手练习 4 ] 批处理计算字符串长度

[复制链接]
发表于 2008-11-28 20:28:13 | 显示全部楼层 |阅读模式
假定一字符串 “123ABC上中下”,计算出这个字符串的长度,即有几个字符。

目的:掌握变量截取与条件判断用法。

要求:让批处理自动计算出字符串的长度。字符串可自定义,暂不考虑特殊字符。

评分:代码可读性 1 分;
   首个新方法 6 分,第二个 5 分,依次类推,最少 2 分;
   一人可多种方法,新方法追加 3 分,已经出现过的方法追加 1 分。
发表于 2008-11-29 13:25:02 | 显示全部楼层
  1. @echo off&setlocal EnableDelayedExpansion
  2. set "var=1234567890   1 $"
  3. :loop
  4. set /a a+=1
  5. if not "!var:~%a%,1!" equ "" (goto :loop) else (echo %var%&echo. %a%&pause)
复制代码
效率极为低下.

评分

参与人数 1PB +7 收起 理由
wxcute + 7 先考虑解决的办法,效率问题慢慢改进。

查看全部评分

发表于 2008-11-29 20:13:58 | 显示全部楼层
对上述的两种方法进行了稍许改进,并且自己新加了一种方法,并加以比较运行效率。得出对于1000个字符的(似乎最长也只能处理长度为1000左右的字符串)长度计算,三楼方法(改进后)比二楼快约500毫秒,新方法(法三)效率与二楼相当,是在我的机子上。所以如果求的字符串数量很多的话(如成千上万个),还是用第二种方法较好!
       测试字符串生成可以用如下命令  @set /p=%random%<nul >>a.txt&%0
       新加了法四,batman的高见!

  1. @echo off&setlocal enabledelayedexpansion
  2. set /p "var=请输入字符串:"
  3. echo ========================
  4. echo [法一]
  5. set time1=%time%
  6. set /a time1_second=1%time1:~-5,2%-100
  7. set /a time1_millisec=1%time1:~-2,2%-100
  8. rem ----------[法一]主程序开始---------------------
  9. :loop
  10. set /a a+=1
  11. if not "!var:~%a%,1!" equ "" goto :loop
  12. echo 共有%a%个字符
  13. rem ----------[法一]主程序结束---------------------
  14. set time2=%time%
  15. set /a time2_second=1%time2:~-5,2%-100
  16. set /a time2_millisec=1%time2:~-2,2%-100
  17. if %time2_millisec% lss %time1_millisec% set /a time2_millisec+=100&set /a time2_second-=1
  18. set /a second=time2_second-time1_second
  19. set /a millisec=time2_millisec-time1_millisec
  20. echo 开始时间:%time1%  结束时间:%time2%
  21. echo 程序1运行时间为%second%秒%millisec%0毫秒
  22. echo ========================
  23. echo [法二]
  24. set time1=%time%
  25. set /a time1_second=1%time1:~-5,2%-100
  26. set /a time1_millisec=1%time1:~-2,2%-100
  27. rem ----------[法二]主程序开始---------------------
  28. for /l %%a in (0,1,10000) do if "!var:~%%a,1!" equ "" set length=%%a&goto end
  29. :end
  30. echo 共有%length%个字符
  31. rem ----------[法二]主程序结束---------------------
  32. set time2=%time%
  33. set /a time2_second=1%time2:~-5,2%-100
  34. set /a time2_millisec=1%time2:~-2,2%-100
  35. if %time2_millisec% lss %time1_millisec% set /a time2_millisec+=100&set /a time2_second-=1
  36. set /a second=time2_second-time1_second
  37. set /a millisec=time2_millisec-time1_millisec
  38. echo 开始时间:%time1%  结束时间:%time2%
  39. echo 程序2运行时间为%second%秒%millisec%0毫秒
  40. echo ========================
  41. echo [法三]
  42. set time1=%time%
  43. set /a time1_second=1%time1:~-5,2%-100
  44. set /a time1_millisec=1%time1:~-2,2%-100
  45. rem ----------[法三]主程序开始---------------------
  46. set count=0
  47. :loop2
  48. set /a num+=1
  49. for /f %%i in ("%num%") do if not "!var:~%%i,1!"=="" goto loop2
  50. echo 共有%num%个字符
  51. rem ----------[法三]主程序结束---------------------
  52. set time2=%time%
  53. set /a time2_second=1%time2:~-5,2%-100
  54. set /a time2_millisec=1%time2:~-2,2%-100
  55. if %time2_millisec% lss %time1_millisec% set /a time2_millisec+=100&set /a time2_second-=1
  56. set /a second=time2_second-time1_second
  57. set /a millisec=time2_millisec-time1_millisec
  58. echo 开始时间:%time1%  结束时间:%time2%
  59. echo 程序3运行时间为%second%秒%millisec%0毫秒
  60. echo ========================
  61. echo [法四] batman's idea
  62. set time1=%time%
  63. set /a time1_second=1%time1:~-5,2%-100
  64. set /a time1_millisec=1%time1:~-2,2%-100
  65. rem ----------[法四]主程序开始---------------------
  66. echo %var%>a.txt
  67. echo.>>a.txt
  68. for /f "tokens=1 delims=:" %%i in ('findstr /o .* a.txt') do set /a length=%%i-2&if not %%i  
  69. equ 0 echo 共有%length%个字符&goto end
  70. :end
  71. del a.txt
  72. rem ----------[法四]主程序结束---------------------
  73. set time2=%time%
  74. set /a time2_second=1%time2:~-5,2%-100
  75. set /a time2_millisec=1%time2:~-2,2%-100
  76. if %time2_millisec% lss %time1_millisec% set /a time2_millisec+=100&set /a time2_second-=1
  77. set /a second=time2_second-time1_second
  78. set /a millisec=time2_millisec-time1_millisec
  79. echo 开始时间:%time1%  结束时间:%time2%
  80. echo 程序4运行时间为%second%秒%millisec%0毫秒
  81. pause>nul
复制代码
刚有些小问题,已修改,大家运行看看!!!

[ 本帖最后由 lhjoanna 于 2008-11-29 21:46 编辑 ]

评分

参与人数 1PB +8 收起 理由
wxcute + 8 新手题也研究得这么细,PF

查看全部评分

发表于 2008-11-29 21:26:08 | 显示全部楼层
大家可以想想怎么利用findstr /o去实现吧
发表于 2008-11-29 21:44:44 | 显示全部楼层
batman的方法果然很好啊,我一直都没有注意到也没有用过参数/o,每一个参数都有存在的价值啊,佩服!刚写出来运行了一下看(不知代码够不够简洁),效率与[法二]相当。很值得推荐啊!在4楼更新了一下!

[ 本帖最后由 lhjoanna 于 2008-11-29 21:46 编辑 ]

评分

参与人数 1PB +3 收起 理由
wxcute + 3 知学善用,追回第四种方法的分。

查看全部评分

发表于 2008-11-29 21:55:17 | 显示全部楼层
[法一]
共有1234568个字符
开始时间:21:54:45.96  结束时间:21:54:45.96
程序1运行时间为0秒00毫秒
========================
[法二]
共有10个字符
开始时间:21:54:45.96  结束时间:21:54:46.05
程序2运行时间为0秒90毫秒
========================
[法三]
共有10个字符
开始时间:21:54:46.05  结束时间:21:54:46.07
程序3运行时间为0秒20毫秒
========================
[法四] batman's idea
命令语法不正确。

有点问题哦
发表于 2008-11-29 21:58:01 | 显示全部楼层
我这里可以啊,你再运行看看??
  1. ========================
  2. [法一]
  3. 共有1021个字符
  4. 开始时间:21:57:20.33  结束时间:21:57:21.52
  5. 程序1运行时间为1秒190毫秒
  6. ========================
  7. [法二]
  8. 共有1021个字符
  9. 开始时间:21:57:21.52  结束时间:21:57:21.70
  10. 程序2运行时间为0秒180毫秒
  11. ========================
  12. [法三]
  13. 共有1021个字符
  14. 开始时间:21:57:21.70  结束时间:21:57:23.00
  15. 程序3运行时间为1秒300毫秒
  16. ========================
  17. [法四] batman's idea
  18. 共有1021个字符
  19. 开始时间:21:57:23.00  结束时间:21:57:23.21
  20. 程序4运行时间为0秒210毫秒
复制代码
经过测试发现[法一]与[法三]在字符数很少时,比如100个以内时会比[法二]和[法四]小,字符数很多时会增到1秒以上,而[法二]和[法四]总是维持在150-250毫秒之间。算法的好坏判断是运行时间(效率)不随测试数据的变化而大幅波动,总是稳定在一定的范围内。所以在求字符串长度中,[法二]与[法四]可以算较好的算法。

[ 本帖最后由 lhjoanna 于 2008-11-29 22:07 编辑 ]
发表于 2008-11-29 22:03:07 | 显示全部楼层
这次就行了
  1. [法一]
  2. 共有83个字符
  3. 开始时间:22:02:01.70&#160;&#160;结束时间:22:02:01.75
  4. 程序1运行时间为0秒50毫秒
  5. ========================
  6. [法二]
  7. 共有83个字符
  8. 开始时间:22:02:01.77&#160;&#160;结束时间:22:02:01.85
  9. 程序2运行时间为0秒80毫秒
  10. ========================
  11. [法三]
  12. 共有83个字符
  13. 开始时间:22:02:01.85&#160;&#160;结束时间:22:02:01.91
  14. 程序3运行时间为0秒60毫秒
  15. ========================
  16. [法四] batman's idea
  17. 共有83个字符
  18. 开始时间:22:02:01.91&#160;&#160;结束时间:22:02:01.95
  19. 程序4运行时间为0秒40毫秒
复制代码
还是batman的牛啊,越长越快捷,但是能够解释一下为什么会多2出来吗?

[ 本帖最后由 BBCC 于 2008-11-29 22:08 编辑 ]
发表于 2008-11-29 22:10:47 | 显示全部楼层
[法四]可以算较好的算法

findstr的牛逼用途导致有那么高的效率
发表于 2008-11-29 22:13:17 | 显示全部楼层
你用findstr /o对一个文本文件进行操作,看一下结果,把数字与冒号也算做偏移量,第二行显示的数字就是第一行字符的长度加上开始的数字与冒号,所以减2就是第一行的字符串长度了。我推测的,没有任何理论依据,还请高手来个权威的解释啊。

[ 本帖最后由 lhjoanna 于 2008-11-29 22:18 编辑 ]
发表于 2008-11-29 22:18:30 | 显示全部楼层
看了一下英语版的帮助,不明白
/O&#160; &#160;&#160; &#160;&#160; &#160rints character offset before each matching line.

在每行之前显示偏移量?

[ 本帖最后由 BBCC 于 2008-11-29 22:20 编辑 ]
发表于 2008-11-29 22:42:49 | 显示全部楼层
关于findstr /o的用法,大家可以参照这个帖子:
http://www.bathome.net/viewthrea ... hlight=%C1%B7%CF%B0
发表于 2008-11-29 22:45:20 | 显示全部楼层

回复 11楼 的帖子

多出来的2个,并非冒号以及前面的数字,而是行尾的回车(CR)和换行(LN)。
发表于 2008-11-29 23:14:30 | 显示全部楼层
原来如此啊,以前总以为回车与换行是一个的。搜索了一下资料,发现回车是回到行首,换行是换到下一行。用二进制编辑器看行尾#13#10,十六进制看行尾为0d0a。说明我们平常输入的回车符其实是两个字符。#13为回车,#10为换行。0d为回车,0a为换行。大家把0d或0a改为00看看。又学到了一点!

[ 本帖最后由 lhjoanna 于 2008-11-29 23:20 编辑 ]
发表于 2009-3-2 17:52:03 | 显示全部楼层

回复 1楼 的帖子

@echo off
set /p tt=please input---
set n=-1
call:circle
goto:eof
:circle
setlocal
set tt1=%tt:~,1%
set tt2=%tt:~1%
set tt=%tt2%_%tt1%
set /a n+=1
if "%tt1%" neq "_" goto circle
echo %n%
endlocal

评分

参与人数 1PB +5 收起 理由
wxcute + 5 不错哦。

查看全部评分

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|批处理之家 ( 渝ICP备10000708号 )

GMT+8, 2026-3-16 21:20 , Processed in 0.032363 second(s), 12 queries , File On.

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表