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

[数值计算] 批处理求字符串长度的表驱动算法


求字符串长度在许多代码中是很关键的子过程

现在综合起来比较好的算是[折半法点击查看代码] 【不用自行管理变量,且效率较高】
判断1000以内长度的字符串 耗费时间单位25,而其他的使用goto命令的耗费时间都和他不在一个数量级上!

对于非常频繁的求字符串长度的代码,还有更好的算法,本帖为大家隆重推荐ifexist的一个小代码,我只是对他的思想做了延伸

算法思想为ifexist的如下代码
  1. set s=%19876543210&echo the length of "%1" is %s:~9,1%
复制代码
查阅相关资料,此种思想算法属于 表驱动算法 范畴


只要你理解预处理的机制,代码是支持所有特殊字符的
:: strlen256 // 最大字符串长度256
setlocal enabledelayedexpansion

::::::::::::如果你觉得下面两句比较耗时间,可以直接把list的值【512字节】求出然后用set命令赋值::::::::::::::::
set zz=0 1 2 3 4 5 6 7 8 9 a b c d e f&set "list="
for %%a in (%zz%)do for %%b in (%zz%)do set list=!list!%%a%%b
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
rem 使用范例 // 【耗费的时间单位仅为 2.3】
set s=your strings
set "s=!list!!s!!s!"&set/a len=0X!s:~-512,2!
echo %len%
下面代码支持字符串的最大长度为1024
:: strlen1024
setlocal enabledelayedexpansion

::::::::::::如果你觉得下面三句比较耗时间,可以直接把list的值【2048字节】求出然后用set命令赋值::::::::::::::::
set zz=0 1 2 3 4 5 6 7 8 9 a b c d e f g h i j k l m n o p q r s t u v
set z=10&(for %%a in (%zz:~20%)do set/a %%a=z,z+=1)&set "list="
for %%a in (%zz%)do for %%b in (%zz%)do set list=!list!%%a%%b
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

rem 使用范例 // 【耗费的时间单位仅为 2.3】
set s=your strings
set "s=!list!!s!!s!"&set/a len=!s:~-2048,1!*10+!s:~-2047,1!
rem 老帖为“set "s=!list!!s!!s!"&set l=!s:~-2048,2!&set/a len=!l:~,1!*10+!l:~-1!”
echo %len%
对于更长的字符串,用类似的方法可以扩充到任意长度[cmd支持最大命令行8K],
根据实际情况需要选定list字符串作为“表”,表的字节数随待求字符串的最大长度 基本上是线性递增的

----------------------------------------------------------- 更新一下 --------------------------------------------------------

关于生成“list表”有快速方法,下面代码生成表耗时用18~25个时间单位
【一个时间单位为一次set 赋值所耗费的时间,点此查看详情
rem 生成strlen256的那个表:
@setlocal enabledelayedexpansion
@set zz= 0 1 2 3 4 5 6 7 8 9 a b c d e f&set list=&for %%a in (!zz!)do set list=!list!!zz: =%%a!
@echo %list%>list.txt
::strlen1024
setlocal enabledelayedexpansion
rem 此表字节数3072,如果嫌太大可以使用原帖那个strlen1024的表,字节数2048
set zz= 0 1 2 3 4 5 6 7 8 9 a b c d e f&set lt=&set "list="
for %%a in (%zz%)do set "lt=!lt!!zz: = %%a!"
for %%b in (%zz:~0,8%)do set "list=!list!!lt: =%%b!"
rem 使用范例
set s=your strings
set "s=!list!!s!!s!!s!"&set/a len=0X!s:~-3072,3!
echo %len%
[ 本帖最后由 plp626 于 2009-10-13 11:22 编辑 ]
5

评分人数

原帖由 随风 于 2009-10-7 06:48 发表
626兄一发帖都是好帖啊,没有一个不让人看得“头痛”的 ^_^


我喜欢拿来主义...

至今没有一个算法的思想 从头到脚全是原创的

[ 本帖最后由 plp626 于 2009-10-12 17:42 编辑 ]

TOP

原帖由 zqz0012005 于 2009-10-7 09:29 发表
算法果然深奥而强大!只是我没怎么接触。。。

变量的最大长度是8KB,用这个方法的缺点是导致被计算字符串长度要再次受到限制。

这种一维完全表太消耗字符串了,要设法换成多维数组之类的另一种表。


字符截 ...


此类算法的思想本质就是根据实际情况选表,最通用的表,一定是占内存最大的;

微软的cmd有点像一个cpu,我们用的命令就是他的基本指令,如果这样理解,cmd功能很弱也无可厚非,

TOP

  1. echo ”%~1“>%tmp%\$
  2. for %%a in (%tmp%\$)do set/a byte=%%~za-4
复制代码
这个是求字符串的字节数 :sizeof("string") =/= strlen("string")

但是话说回来,对于纯英文的字符,这个代码不是一般的健壮,

[ 本帖最后由 plp626 于 2009-10-7 20:49 编辑 ]
1

评分人数

    • 523066680: 猛nan,向你学习了……PB + 30

TOP

返回列表