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

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

[复制链接]
发表于 2015-7-8 17:46:56 | 显示全部楼层 |阅读模式
今天看到了[plp626]的帖子——http://www.bathome.net/thread-11799-1-1.html
初步接触,感觉这些想法都太厉害了。以前以为能递归算出字符串长度就可好了,呵呵。

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

下面算法思想是基于16查表法,先求出待测字符串长度对16的"倍数值",再求对16的余数值;最后相加
发表于 2015-7-8 18:03:23 | 显示全部楼层
本帖最后由 CrLf 于 2015-7-8 18:15 编辑

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


    嗯,表驱动这个,确实是很厉害。不过单纯的表驱动算法,是09年的帖子了。
    所以[plp626]的这个算法是11年的基于表驱动的一个算法,虽然算的字符串也不长,但是应该很巧很快的。不过执行体没了。时间确实太久了。
    刚接触批处理,所以好奇心比较大。
发表于 2015-7-8 18:33:52 | 显示全部楼层
回复 3# 回家路上


    看懂了原理,可以自己实现一下,这不是很复杂,然后想想有没有不兼容的特殊情况,能否避免或解决
发表于 2015-7-8 19:35:28 | 显示全部楼层
回复 5# tigerpower


    不见得噢,第三方的优势是高集成、执行快,缺点是启动慢、应变差,尤其是 strlen 这样的小功能,用内部命令的效率远胜于调用第三方
发表于 2015-7-8 21:06:20 | 显示全部楼层
回复 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
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-3-18 13:25 , Processed in 0.016238 second(s), 8 queries , File On.

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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