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

[分享]批处理折半法获取变量的长度(即:字符数)

获取变量的长度(即:字符数)
目前常见的方法好像只有一种,那就是逐字判断,也就是一个一个的去数,
此种方法虽能实现但有两个最大的缺点
一、逐字判断,效率很低,速度取决于变量的长度,越长就越慢。
二、必须使用goto进行循环,若是对文本逐行进行判断时还必须用call先跳出for又一次影响效率
.
以下代码打破了此种常规,无论变量的字符数是多少,(1-8189)
for /L 都只需循环14次即可得到结果,且不用goto和call
原理很简单
首先我们知道变量的最多字符数为8192这其实是包括了变量名和等号及set后面的那个空格,所以变量的实际长度最多只允许有8189个。
首先判断变量是否为超过8189个,如果没有则把8189除以2再判断,再没有再除以2
如此经过几次循环就能得到变量字符数的上限和下限,也就是大大缩小了范围,再在此范围内重复前面的循环即可得到最终结果。
为考虑极端情况(字符数为8189个时)所以代码中变量名必须是单一字母,且不能加引号。
书写时注意别在后面误加空格。。。
  1. @echo off&rem 判断变量长度 折半法
  2. ::@随风 @bbs.bathome.net @2009-04-18
  3. for /f "delims=" %%a in (a.txt) do (
  4.    set s=%%a&set /a sun+=1
  5.    setlocal enabledelayedexpansion&set "var="
  6.    set /a n=8189*2,max=1
  7.    for /l %%a in (1 1 14) do (
  8.       if defined var set /a n=var
  9.       set /a n/=2
  10.       for %%i in (!n!) do (
  11.          if "!s:~%%i,1!"=="" (set /a var=n) else (
  12.             set s=!s:~%%i!&set /a max+=%%i,var-=%%i
  13.    )))  
  14.    echo 第!sun! 行的字符数为: !max! 个
  15.    endlocal
  16. )
  17. pause
复制代码
以下是函数封装
  1. :loop 不能处理%号,变量字符数上限为8187个。
  2. ::@随风 @bbs.bathome.net @2009-04-18
  3. set "s=%~1"&rem 判断变量长度(封装)折半法
  4. setlocal enabledelayedexpansion
  5. set /a n=8189*2,max=1&set "var="
  6. for /l %%a in (1 1 14) do (
  7.    if defined var set /a n=var
  8.    set /a n/=2
  9.    for %%i in (!n!) do (
  10.       if "!s:~%%i,1!"=="" (set /a var=n) else (
  11.          set s=!s:~%%i!&set /a max+=%%i,var-=%%i
  12. )))  
  13. endlocal&set %~2=%max%&goto :EOF
复制代码

[ 本帖最后由 随风 于 2009-4-18 17:00 编辑 ]
2

评分人数

技术问题请到论坛发帖求助!

计算字符串长度,这个话题经久不息啊。。。

这个算法很不错。。。
第三方命令行工具编程
Http://Hi.Baidu.Com/Console_App

TOP

回复 3楼 的帖子

字符数不是字节,无论是单个汉字还是单个字母都是一个字符。
技术问题请到论坛发帖求助!

TOP

回复 5楼 的帖子

第一步、判断变量第8190位是否为空
第二步、若为空,则 8190/2=4095 判断变量第 4096位是否为空
第三步、若为空、则 4095/2=2047 判断变量第 2048位是否为空
。。。。。。。。。
。。。。。。。。。
直到不为空,假设第三步以不为空,则得出变量字符数上限为4095下限为2047,再在这个范围内重新判断。
技术问题请到论坛发帖求助!

TOP

回复 7楼 的帖子

可以google搜索“折半查找法”,学习一下思路。
我帮忙写的代码不需要付钱。如果一定要给,请在微信群或QQ群发给大家吧。
【微信公众号、微信群、QQ群】http://bbs.bathome.net/thread-3473-1-1.html
【支持批处理之家,加入VIP会员!】http://bbs.bathome.net/thread-67716-1-1.html

TOP

折半查找法 ?
原来还有专业术语?查查看。。。
技术问题请到论坛发帖求助!

TOP

二分法总是伟大的!

TOP

请问
  1. set s=!s:~%%i!&set /a max+=%%i,var-=%%i
复制代码
是怎么执行的或是怎样理解?!

    我想了很久就是得不出所以然??

TOP

回LS:

代码等同于

set s=!s:~%%i!
set /a max=max+%%i
set /a var=var-%%i
第三方命令行工具编程
Http://Hi.Baidu.Com/Console_App

TOP

回复 1楼 的帖子

好。这就是数学上的闭区间套定里的原理。破有点数学上的逼近的思想是味道。

TOP

辅以小代码帮大家理解折半法:
  1. @echo off&rem 利用折半法准确判断输入数
  2. set /p input=请输入一个整数:
  3. set /a min=1^<^<31,max=~min&rem max、min分别为cmd所能处理的最大、最小数
  4. :loop
  5. set /a pin=(max+min)/2&rem 折半
  6. if %input% lss %pin% set /a max=pin
  7. if %input% equ %pin% goto end
  8. if %input% gtr %pin% set /a min=pin
  9. set /a n+=1&goto loop
  10. :end
  11. cls&echo 循环了%n%次得出输入的数是%pin%
  12. pause>nul     
复制代码

[ 本帖最后由 batman 于 2009-4-19 12:00 编辑 ]
1

评分人数

***共同提高***

TOP

首先我们知道变量的最多字符数为8192

从何得知?到底是字节数还是字符数?

TOP

回复 16楼 的帖子

1

评分人数

    • rat: 感谢指点PB + 6
我帮忙写的代码不需要付钱。如果一定要给,请在微信群或QQ群发给大家吧。
【微信公众号、微信群、QQ群】http://bbs.bathome.net/thread-3473-1-1.html
【支持批处理之家,加入VIP会员!】http://bbs.bathome.net/thread-67716-1-1.html

TOP

TOP

我还有更好的方法!
  1. @echo off
  2. set /p w=请输入一些文字:
  3. setlocal EnableDelayedExpansion
  4. for /l %%b in (0 1 8192) do (
  5. if "!w:~%%b,1!"=="" (echo 你输入了%%b个字!&goto a))
  6. :a
  7. pause
复制代码

TOP

返回列表