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

[文本处理] 批处理求字符串长度

今天看到了[plp626]的帖子——http://www.bathome.net/thread-11799-1-1.html
初步接触,感觉这些想法都太厉害了。以前以为能递归算出字符串长度就可好了,呵呵。

在二楼列出的所有优秀算法中,最后一种就写了一半?是怎么回事,而且说该算法,比第一种还快,不知道谁有,还能不能看着。

下面算法思想是基于16查表法,先求出待测字符串长度对16的"倍数值",再求对16的余数值;最后相加

本帖最后由 CrLf 于 2015-7-8 18:15 编辑

就是 http://www.bathome.net/viewthread.php?tid=5994 的表驱动法吧
表驱动法应该是最快的,不过缺陷也很明显:要先生成表,而且考虑到变量长度上限,最多只能计算短于 4095 个字符的字符串
原版单张表是最快的,不过因为需要三倍的表,所以上限止于 2047(写出来你就明白了),若要再提升到 4095,需要一张 16 位副表配合,用于单独计算 16 进制的个位数

TOP

回复 2# CrLf


    嗯,表驱动这个,确实是很厉害。不过单纯的表驱动算法,是09年的帖子了。
    所以[plp626]的这个算法是11年的基于表驱动的一个算法,虽然算的字符串也不长,但是应该很巧很快的。不过执行体没了。时间确实太久了。
    刚接触批处理,所以好奇心比较大。

TOP

回复 3# 回家路上


    看懂了原理,可以自己实现一下,这不是很复杂,然后想想有没有不兼容的特殊情况,能否避免或解决

TOP

回复 5# tigerpower


    不见得噢,第三方的优势是高集成、执行快,缺点是启动慢、应变差,尤其是 strlen 这样的小功能,用内部命令的效率远胜于调用第三方

TOP

回复 7# tigerpower


十几万行这么大的量必然是用第三方更快,但平时并不是很经常碰到这种处理大量数据的情况,事实上,很多时候文本不是最终目的,即使必须处理大数据,也不是单独一个第三方能独立完成的,所以第三方是了解得越多越好,但同时对 shell 本身的功能还是要有一定理解,才能把好钢用在刀刃上。
若是判断 set 中所有变量的长度,或判断伪数组 array[0]..array[N] 的长度,兄台可以试试结果
这里举个示例,判断某变量的长度100次的测试:
  1. @echo off & setlocal enabledelayedexpansion
  2. set "str=fjalskdjfowjeeoisfjasdlkkjfpoawiecjokawenfocjseadkfjdskjflj"
  3. (
  4.    (for /l %%a in (1 1 100) do gawk "BEGIN{print length(\"!str!\")}") <nul >nul
  5.    echo Gawk*100 Start at %time%, End at !time!
  6. )
  7. (
  8.    (for /l %%a in (1 1 100) do call :strlen str) >nul
  9.    echo Call*100 Start at %time%, End at !time!
  10. )
  11. (
  12.    (for /l %%a in (1 1 100) do (
  13.       set "$=!str!#"
  14.       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!
  15.       echo !len!
  16.    )) >nul
  17.    echo inline*100 Start at %time%, End at !time!
  18. )
  19. pause
  20. :strlen
  21. setlocal enabledelayedexpansion
  22. set "$=!%1!#"
  23. 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!
  24. endlocal&If %2. neq . (set/a%2=%len%)else echo %len%
复制代码
本机结果,这种频繁调用的情况下,即使是批处理中效率很低的 call 也比调用 gawk 快,更不要说内联了:
Gawk*100 Start at 20:55:26.33, End at 20:55:26.70
Call*100 Start at 20:55:26.70, End at 20:55:26.90
inline*100 Start at 20:55:26.90, End at 20:55:26.94

TOP

返回列表