Board logo

标题: 【练习-002】批处理查找字符数最多的文本行 [打印本页]

作者: batman    时间: 2008-7-26 01:40     标题: 【练习-002】批处理查找字符数最多的文本行


有文本a.txt如下:
  1. aaaaaaa                                 aaaa bbbbbb ccccccccccc dddd
  2. aa  aaaaaaa bbbbbbbb cccccccccc ddddddddddddd eeeeeee
  3.      aaaaaaaaaaaa bbbbbbbbbbb cccccccccccccccccccc
  4.                 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aa
  5.                     aaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbb
  6. aaaaaaaaa        ccccccccc bbbbbbbbbbbbb               ddddddddddddddddd
复制代码
通过批处理查找出文本中字符数(不含空格)最多的行并输出,很明显就是
  1. aaaaaaaaa        ccccccccc bbbbbbbbbbbbb               ddddddddddddddddd
复制代码
要求:
1 不生成临时文件
2 代码简洁,高效,通用性好
3 加分仍以思路为重

----------------------------------------------------------------------------------------------------------------------------------------------------
至目前已有解决方案:见3楼浅默和4楼本人的方案,期待更多方案的出现。







[ 本帖最后由 batman 于 2008-7-27 23:58 编辑 ]
作者: pusofalse    时间: 2008-7-26 02:18

这题还要输出最多的字符在第几行吗?
如果是,包含空行吗?
作者: 浅默    时间: 2008-7-26 06:29

@echo off
Setlocal Enabledelayedexpansion
set n=0
for /f "delims=" %%i in (a.txt) do (
      set "ke=%%i"
      set ke1=!ke: =!
      set m=0
      call :1                  
)
echo %wang%
pause
goto :eof
:1
  if not "!ke1:~%m%,1!"=="" set /a m+=1&goto 1
  if %m% gtr %n% set n=%m%&set wang=%ke%
  goto :eof
作者: batman    时间: 2008-7-26 08:19

下面给出本人的方案一:
  1. @echo off
  2. set num=0
  3. for /f "delims=" %%i in (a.txt) do  set "str=%%i"&call,set "str=%%str: =%%"&call :lp "%%i"
  4. call,echo %%_%num%%% %num%个字符
  5. pause>nul&goto :eof
  6. :lp
  7. set "str=%str:~1%"&set /a n+=1
  8. if defined str goto lp
  9. if %n% geq %num% set "num=%n%"&set "_%num%=%~1"
  10. set "n=0"
复制代码

[ 本帖最后由 batman 于 2008-7-26 18:25 编辑 ]
作者: pusofalse    时间: 2008-7-26 16:43

原帖由 batman 于 2008-7-26 08:19 发表
下面给出本人的方案一:@echo off
set num=0
for /f "delims=" %%i in (a.txt) do  set "str=%%i"&call,set "str=%%str: =%%"&call :lp "%%i"
call,echo %%_%num%%% %num%个字符
pause>nul&goto :eof
:lp
set  ...


有一点小错误,加完分才看出来。变量%%_%num%%是字符数最多的行,没有进行条件约束而每次都赋值给它,导致输出的字符数正确,行的内容却每次都是最后的那一行。
作者: batman    时间: 2008-7-26 18:26

确实如此,粗心了,谢谢兄弟指出。
作者: namejm    时间: 2008-7-30 10:59

  可以考虑 findstr /o 方案。
/O        在每个匹配行前打印字符偏移量。

作者: batman    时间: 2008-7-31 13:09

原帖由 namejm 于 2008-7-30 10:59 发表
  可以考虑 findstr /o 方案。

思路是对的,但实施起来还真的有点麻烦:
  1. @echo off&setlocal enabledelayedexpansion
  2. set "max=0"
  3. for /f "delims=" %%i in (1.txt) do set "str=%%i"&echo !str: =!>>2.txt
  4. echo end>>2.txt
  5. for /f "tokens=1* delims=: " %%i in ('findstr /o .* 2.txt') do (
  6.     set /a n+=1&set "_!n!=%%i"&set ".!n!=%%j"
  7.     set /a m=n-1
  8.   if !m! geq 1 call :lp
  9. )
  10. echo.&echo 字符数最多的行为:!a%max%!
  11. echo.&echo     字符数为:%max%个   
  12. del /q 2.txt&pause>nul&goto :eof
  13. :lp
  14. set /a num=_%n%-_%m%-2
  15. if %num% gtr %max% set "max=%num%"&set "a!max!=!.%m%!"
复制代码

作者: keen    时间: 2009-4-17 23:28

太复杂了,想办法优化:
  1. @echo off&setlocal enabledelayedexpansion
  2. for /f "delims=" %%i in (a.txt) do (
  3.     set v=%%i
  4.     set n=0
  5.     set /a m+=1
  6.     call :lp
  7.     set _!m!=!n!#%%i
  8. )
  9. set max=0
  10. call :next
  11. for /f "tokens=1 delims=#" %%a in ("!var!") do (
  12.         set s=%%a
  13.         if !s! gtr %max% set max=!s!
  14. )
  15. call :next
  16. for /f "tokens=1,2 delims=#" %%a in ("!var!") do (
  17.         if %%a==%max% echo %%b
  18. )
  19. pause&exit/b
  20. :next
  21. for /l %%i in (1 1 %m%) do (
  22.     set c=%%i
  23.     call,set var=%%_!c!%%
  24. )
  25. goto :eof
  26. :lp
  27.     if "!v:~0,1!" neq " " set /a n+=1
  28.     set v=!v:~1!
  29.     if "!v!" neq "" goto lp
  30. goto :eof
复制代码

作者: batman    时间: 2009-4-17 23:41

回复楼上:
兄弟看来是特有求知欲和动手欲的,这么老的练习贴子也让你翻到了,还做了解答,呵呵,加油。。。
作者: keen    时间: 2009-4-17 23:52

只能优化成3楼的了:
  1. @echo off&setlocal enabledelayedexpansion
  2. for /f "delims=" %%i in (a.txt) do (
  3.     set v=%%i
  4.     set /a max=0,n=0,m+=1
  5.     call :lp
  6.     if !n! gtr !max! set max=!n!&set xx=%%i
  7. )
  8. echo %xx%&pause&exit/b
  9. :lp
  10.     if "!v:~0,1!" neq " " set /a n+=1
  11.     set v=!v:~1!
  12.     if "!v!" neq "" goto lp
  13. goto :eof
复制代码

作者: keen    时间: 2009-4-17 23:55     标题: 回复 10楼 的帖子

我是新手,刚从新手训练营出来。
我从新手训练营出来后,就迷失方向了,不知道怎么继续学批处理了,我把论坛挨个翻了一遍,又发现在这一块,有好多题。
我就继续练下去。
请batman多多指教!
作者: batman    时间: 2009-4-18 00:04

呵呵,这块确实是很多人没有注意到的,如果说学批处理有速成班的话,这块就算是的吧。。。
祝兄弟学得开心并学有所成,本人将尽一切能力帮助学习批处理的新人们。
作者: everest79    时间: 2009-4-18 01:35

  1. @echo off
  2. for /f "delims=" %%a in (1.txt) do (
  3. for %%b in (%%a) do call :xxx "%%b"
  4. call :yyy
  5. )
  6. for /f "tokens=2,3 delims=_=" %%i in ('set l_^|sort /+4') do set msg=最长的行为:%%i  长度为:%%j
  7. echo %msg%
  8. pause
  9. goto :eof
  10. :xxx
  11. set "lines=%lines%%~1"
  12. goto :eof
  13. :yyy
  14. set /a x+=1
  15. for /f "skip=1 delims=:" %%i in ('^(echo "%lines%"^&echo.^)^|findstr /o ".*"') do set/a l_%x%=%%i-5
  16. set lines=
  17. goto :eof
复制代码
只处理这个文本
作者: tireless    时间: 2009-4-18 02:06

  1. @echo off
  2. set max=0
  3. for /f "tokens=*" %%a in (a.txt) do (
  4.   if "%%a" neq "" call :ready "%%a"
  5. )
  6. echo 第 %strline% 行字数最多,共 %max% 个字符:&echo.&echo %str%&echo.
  7. pause & exit /b
  8. :ready
  9. set var=%~1
  10. set var=%var: =%
  11. set /a n=0,line+=1
  12. :lp
  13. set fifteen=%var:~,15%fedcba987654321
  14. set /a n+=0x%fifteen:~15,1%
  15. if "%var:~15%" neq "" set "var=%var:~15%" & goto lp
  16. if %n% gtr %max% set /a "max=n,strline=line" & set str=%~1
复制代码

作者: batman    时间: 2009-4-18 02:40

如果文本行都在80个字符以内的话,可用以下这种高效的办法:
  1. @echo off&setlocal enabledelayedexpansion
  2. for /l %%a in (1,1,80) do set "k=!k!0"
  3. for /f "delims=" %%a in (a.txt) do (
  4.     set "str=%%a"&set "str=%k% !str: =!"
  5.     set "str=!str:~-80!"&set /a n+=1
  6.     for /f %%b in ("!str!") do set "_%%b=%%a"&set ".%%a=!n!"
  7. )
  8. for /f "tokens=1,2 delims==_" %%a in ('set _') do (
  9.     set "str=%%a"&set "var=%%b"
  10.     for /l %%i in (1,1,80) do if "!str:~%%i!" equ "" set /a num=79-%%i&goto next
  11. )
  12. :next
  13. echo 字符数是多的是!.%var%!行,共有%num%个字符。
  14. pause>nul
复制代码

作者: 随风    时间: 2009-4-18 15:44

折半法 可处理每行最多 8189 个字符,效率不错。
  1. @echo off&setlocal enabledelayedexpansion
  2. ::@随风 @bbs.bathome.net @2009-04-18
  3. for /f "delims=" %%a in (a.txt) do (
  4.    set /a sun+=1,n=8189*2,max=1
  5.    set s=%%a&set s=!s: =!&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.    if !h! lss !max! set /a num=sun,h=max
  14. )
  15. echo 字符数最多的行为:!num!
  16. echo 字符数为:!h!
  17. pause
复制代码

[ 本帖最后由 随风 于 2009-4-18 17:01 编辑 ]
作者: netbenton    时间: 2009-4-30 00:16     标题: 取长补短为提速

  1. @echo off&setlocal enabledelayedexpansion
  2. set m=0
  3. for /f "delims=" %%a in (a.txt) do (
  4.     set "str=%%a"&set "str=!str: =!0"
  5.     for %%b in (!m!) do (if "!str:~%%b,1!" neq "" call :sub "%%a")
  6. )
  7. echo 字符数是多的是%var%行,共有%m%个字符。
  8. pause
  9. goto :eof
  10. :sub
  11. set/a en=m+40
  12. for /l %%a in (!m!,1,!en!) do (
  13. if "!str:~%%a,1!" equ "" (
  14.   set/a n=%%a-1
  15.   if !m! lss !n! set/a m=!n!,n=0&set "var=%~1"
  16.   goto :eof
  17. )
  18. )
  19. set/a m=en
  20. goto :sub
复制代码

作者: netbenton    时间: 2009-4-30 00:30

请留意中间的输出,此法应该是最高效了吧?
  1. @echo off&setlocal enabledelayedexpansion
  2. set m=1
  3. for /f "delims=" %%a in (a.txt) do (
  4.     set "str=%%a"&set "str=!str: =!0"
  5.     for %%b in (!m!) do (if "!str:~%%b,1!" neq "" call :sub "%%a")
  6. )
  7. set /a m-=1
  8. echo 字符数是多的是%var%行,共有%m%个字符。
  9. pause
  10. goto :eof
  11. :sub
  12. set/a en=m+40
  13. for /l %%a in (!m!,1,!en!) do (
  14.         if "!str:~%%a,1!" equ "" (
  15.                 echo 较多: %~1
  16.         set/a m=%%a&set "var=%~1"&goto :eof)
  17. )
  18. set/a m=en
  19. goto :sub
复制代码

作者: 随风    时间: 2009-4-30 01:33

19楼思路非常巧妙,从少到多,只判断字符数多的行,不判断少的行。省略了很多无用的判断。
作者: qzwqzw    时间: 2010-1-5 10:41

看来从心动到行动
还有很长的距离啊
  1. ::  GetMaxCharText.cmd - 找出字符最多的文本行
  2. ::  qzwqzw - 2010-01-05
  3. ::
  4. ::  基本构思:
  5. ::      将原文本每行尾部加足够的一定数量的空格,在文本右侧形成一个不等齐空格区域
  6. ::      原文本行越长,其后的空格区域就越长,然后用sort /+n 仅对空格区域进行排序
  7. ::      因为区域内都是空格,则排序的依据就是空格的长度,也就是原行文本的长度
  8. ::
  9. @echo off & setlocal EnableDelayedExpansion
  10. set maxLineLen=80
  11. set infile=%~sf0
  12. for /l %%i in (1,1,%maxLineLen%) do set zone= !zone!
  13. :: findstr 会忽略空行和仅含空格的行,但显示行号会跨过这些行,这是我们需要的特性
  14. :: 将行号与行文本分别处理,是因为不对齐行号会影响行文本长度的判断
  15. (for /f "tokens=1* delims=:" %%l in ('findstr /n /r /c:"[^ ]"  %infile%') do (
  16.     set LineNo=         %%l
  17.     set LineNo=!LineNo:~-10!
  18.     set Line=%%m
  19.     set Line=!Line: =!
  20.     echo.!LineNo!:!Line!!zone!
  21. ))>%temp%\%~sn0~1.t~1
  22. sort /r /+%maxLineLen% %temp%\%~sn0.t~1 > %temp%\%~sn0.t~2
  23. set/p maxLine=< %temp%\%~sn0.t~2 >nul
  24. ::  已找到最多字符的行,以下是提取行号和原行文本,行长度因未要求而忽略
  25. for /f "delims=: " %%i in ("%maxline%") do set maxLineIdx=%%i
  26. ::  使用find而不是findstr,是因为find够用够简单
  27. set seekLine=find /v /n "" ^^^<%infile%^^^|find "[%maxLineIdx%]"
  28. echo.字符最多的行第 %maxLineIdx% 行,内容为:
  29. for /f "tokens=1* delims=[]" %%l in ('%seekLine%') do echo.%%m
  30. for %%f in (%temp%\%~sn0.t*) do del %%f
复制代码

[ 本帖最后由 qzwqzw 于 2010-1-5 10:46 编辑 ]
作者: vincentzhou    时间: 2011-1-2 20:56

  1. @echo off&setlocal enabledelayedexpansion
  2. for /f "delims=" %%a in (a.txt) do (
  3.      set /a t+=1
  4.      set i=%%a
  5.      set y!t!=!i!
  6.      set i=!i: =!
  7.      call:x !i!
  8.      set /a n!t!=!num!
  9. )
  10. for /l %%b in (1 1 !t!) do (
  11. if !n%%b! lss !number! (
  12. set /a n%%b=number
  13. set y%%b=!str!
  14. )
  15. set /a number=n%%b
  16. set str=!y%%b!
  17. cls
  18. echo 字符数最多的行是:!y%%b!共有字符:!n%%b! 个
  19. )
  20. pause>nul&exit
  21. :x
  22.     set i=%1
  23.     set num=
  24. :loop
  25.      set i=!i:~1!
  26.      set /a num+=1
  27.      if "!i!"==""  ( echo abc >nul
  28.      )  else ( goto:loop)
复制代码

[ 本帖最后由 vincentzhou 于 2011-1-9 13:27 编辑 ]
作者: CrLf    时间: 2011-5-15 10:29

本帖最后由 zm900612 于 2011-5-16 13:28 编辑

来一个以sort为核心的全新思路:
  1. @echo off&setlocal enabledelayedexpansion
  2. set /a $=11,n=4096
  3. for /l %%a in (-2 1) do set $=!$!!$!!$!!$!
  4. (copy a.txt %$%$&findstr .* %$%?>$
  5. for %%a in (2048 1024 512 256 128 64 32 16 8 4 2 1) do sort /+100 /rec !n! $&&set /a n-=%%a,h=n-130||set /a n+=%%a)>nul 2>nul
  6. for /f "delims=" %%a in ('sort /+%h% a.txt') do set long=%%a
  7. echo !long!
  8. del /f /q *$&pause
复制代码
看到这题又浮了上来,想起正好能用上前阵子开发的用sort命令判断文件中最长行字符数的代码,于是把代码改造了下...
这种以外部命令为主的算法计算小文件时不快,但是在计算大文件时将有速度优势。
作者: qzwqzw    时间: 2011-5-15 21:21

23# zm900612
代码过于求奇求异
又缺乏必要的注释
是在考验读者的耐心
我不欣赏这样的风格
作者: CrLf    时间: 2011-5-16 13:26

本帖最后由 zm900612 于 2011-5-16 13:37 编辑
23# zm900612
代码过于求奇求异
又缺乏必要的注释
是在考验读者的耐心
我不欣赏这样的风格
qzwqzw 发表于 2011-5-15 21:21

求奇求异倒不是刻意为之,只是平时喜欢发掘命令的新鲜用法,积累多了,在特定的场合自然会联想到,如果别人不了解我的积累,肯定不容易一下就看明白思路是什么...至于注释,确实没有养成这个代码习惯,以后会注意。

附上对23楼代码的解读:
首先要先说明一下,核心代码来自于前不久研究sort的rec开关时想到的用法:
  1. @echo off&setlocal enabledelayedexpansion
  2. set n=32768
  3. (for %%a in (16384 8192 4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do sort /+100 /rec !n! 1.txt&&set /a n-=%%a||set /a n+=%%a)>nul 2>nul
  4. ::很像plp兄曾转发过的折半回溯法求字符长度的函数吧?是的,这里就是对那个思路的改造,只不过我是利用sort /rec超过最长行字数时会出错的特性来进行运算的。
  5. echo 最长行有%n%个字符
  6. pause
复制代码
但是当时这个代码有个缺点,就是当最长行的字数低于128时,sort /rec的值无论设为多少都是不会出错的。
好在曾经拜读过用findstr实现多色显示的代码,从中获取了灵感,于是23楼代码中就用同样的原理为a.txt中每行补齐128个字符的前缀,这样就绕过了原先的限制
23楼代码为了简化而写得比较晦涩,现在翻译成大众版:
  1. @echo off&setlocal enabledelayedexpansion
  2. set /a tmp=11,n=4096
  3. ::此处的tmp是用于补位的,设成任意两个字符都行,为了压缩代码,把它设成十位数
  4. for /l %%a in (1 1 3) do set tmp=!tmp!!tmp!!tmp!!tmp!
  5. ::将tmp补足128位
  6. copy>nul a.txt %tmp:~2%$
  7. ::将a.txt保存到一个文件名长度为127个字符的临时文件中
  8. findstr .* %tmp:~2%?>$
  9. ::用findstr命令配合通配符实现补位,127个字符长的文件名加上“:”号,刚好128个字符,将结果输出到临时文件中
  10. for %%a in (2048 1024 512 256 128 64 32 16 8 4 2 1) do (
  11.    sort /+100 /rec !n! $&&set /a n-=%%a,h=n-128||set /a n+=%%a
  12. )>nul 2>nul
  13. ::用sort /rec判断该临时文件最长行的长度
  14. for /f "delims=" %%a in ('sort /+%h% a.txt') do set long=%%a
  15. ::因为知道了最长行的长度,所以可以直接用sort /+n来精确排序,通过for命令,很容易获得最后一行的内容(用set /p也可以,但是考虑到变量长度,还是用for保险,当然用findstr取指定行也是一个不错的选择)。
  16. echo !long!
  17. ::不解释
  18. del /f /q *$
  19. ::删除临时文件,销赃
  20. pause
复制代码

作者: CrLf    时间: 2011-5-16 13:34

23楼的代码中,至少用了三种比较偏门的技巧,所以看起来就显得奇异一些...
作者: qzwqzw    时间: 2011-5-16 15:28

代码看着顺畅多了
不需要实际测试与断点跟踪也能明白思路
给两个建议:
1、set /a h=n-128移到for之外
2、取最长行用for/f+sort又成为线性算法
for/f需要完整遍历整个文件才能取得最长行
与你通篇的算法思路相左
不如仍然用set/p+sort /r
至于变量长度这与for/f中的set long有不同吗?
作者: qzwqzw    时间: 2011-5-16 15:30

另外发现一个小问题
悄悄的告诉你
楼主的题目要求是获取不包含空格的字符数最多行
作者: CrLf    时间: 2011-5-16 16:47

代码看着顺畅多了
不需要实际测试与断点跟踪也能明白思路
给两个建议:
1、set /a h=n-128移到for之外
2、取最长行用for/f+sort又成为线性算法
for/f需要完整遍历整个文件才能取得最长行
与你通篇的算法思路相 ...
qzwqzw 发表于 2011-5-16 15:28


1、这个,如果没记错的话,一个set /a的用时好像是set /a内部二十几个算式的计算耗时,而此处实际上只需要计算12次,所以我感觉这个算式还是能联用就联用
2、最初确实忽略了思路的连贯性,刚刚解释代码的时候也想到这一点,所以加了句用“findstr也是不错的选择”
关于变量长度,set /p与set的区别在于set "str=#@#¥#……&"时变量长度上限8192字节,而set /p str=请输入#@#¥#……&时则只能定义1024字节,这与前面折半回溯所支持的字符长度相悖,所以放弃了set /p。
改进的思路是:
  1. endlocal
  2. for /f "tokens=1* delims=:" %%a in ('findstr /n a.txt^|findstr 1:') do set "long=%%b"
  3. ...
复制代码
3、没看到楼主要求是不含空格,不过好像在谁的代码中看到了"findstr /o"...
我的代码习惯可能比较明显,要么大量使用外部命令,要么一堆for嵌套+set,减少call和goto。如果碰到大文件,外部命令优势明显,但是若要进行更精细的筛选,那还是只好老老实实用for了...
作者: qzwqzw    时间: 2011-5-16 20:11

set /a的问题不是在效率上
而是在逻辑上
因为你在set /a n+=%%a时并没有计算h
那么如果set /a n-=%%a在特定条件下没有运行一次
那么h的取值为空
或者set /a n-=%%a最后一次没有运行
那么h的取值会差1

set/p的字符长度限制确实是忘记了
记忆力确实越来越差了
扩展测试了一下
windows记事本也有每行1024字符的限制
find命令同样也有

不过你的改进思路有些问题
似乎忘记了sort /r
作者: CrLf    时间: 2011-5-16 20:48

本帖最后由 zm900612 于 2011-5-16 21:16 编辑
set /a的问题不是在效率上
而是在逻辑上
因为你在set /a n+=%%a时并没有计算h
那么如果set /a n-=%%a在特定条件下没有运行一次
那么h的取值为空
或者set /a n-=%%a最后一次没有运行
那么h的取值会差1

set/p ...
qzwqzw 发表于 2011-5-16 20:11

这个确实没想到,没顾虑到特殊情况。

关于改进思路,汗一个,错了不止一处,应该改成:
  1. endlocal
  2. for /f "tokens=1* delims=:" %%a in ('sort /r /+%h% a.txt^|findstr /n .*^|findstr /b 1:') do set "long=%%b"
  3. ...
复制代码

作者: qzwqzw    时间: 2011-5-16 21:05

怎么看怎么觉得这个修改后的代码仍然有问题
没有实测
就是觉得sort 既不用+%h% 也不用 /r
会将a.txt排序成什么样子
而第二个findstr 为什么还会用a.txt?
作者: CrLf    时间: 2011-5-16 21:16

32# qzwqzw


又忘了,已修改
作者: Hello123World    时间: 2011-7-20 14:31

本帖最后由 Hello123World 于 2011-7-20 14:33 编辑

模仿3楼的算法,手动写一个。
  1. @echo off & Setlocal EnableDelayedExpansion
  2. set n=0
  3. ::本以为变量不定义,用时值就自动是零,这里不定义n,后面就会出错。
  4. For /f "delims=" %%i in (a.txt) do (
  5. Set "a=%%i"
  6. Set a1=!a: =!
  7. Set str=0
  8. Call :hello
  9. )
  10. echo %max%
  11. pause
  12. Goto :eof
  13. :hello
  14. If Not "!a1:~%str%,1!"=="" Set /a str+=1 & Goto hello
  15. ::此句用来计算字符串长度
  16. If %str% gtr %n% Set n=%str%&Set max=%a%
  17. Goto :eof
复制代码
说到底,知识就是那些,关键还是看怎么用(算法)。
作者: CrLf    时间: 2011-8-6 01:11

在循环中非常高效的表驱动法:
  1. @echo off&setlocal enabledelayedexpansion
  2. set "tmp= 0 9 8 7 6 5 4 3 2 1"
  3. for /l %%a in (0 1 4) do set var=!tmp: =%%a!!var!
  4. for /f "delims=" %%a in (a.txt) do (
  5. set str=%%a
  6. set m=!str: =!!str: =!!var!
  7. if "1!m:~100,2!" gtr "1!max!" (
  8. set max=!m:~100,2!
  9. set text=%%a
  10. )
  11. )
  12. echo !text!
  13. pause
复制代码
同样的算法稍加改动,日后最多可以兼容四千多位:
  1. @echo off&setlocal enabledelayedexpansion
  2. for /l %%a in (1 1 5) do set a=!a!0987654321
  3. for /l %%a in (0 1 4) do set b=%%a%%a%%a%%a%%a%%a%%a%%a%%a%%a!b!
  4. for /f "delims=" %%a in (a.txt) do (
  5. set str=%%a
  6. set m=!str: =!!a!
  7. set n=!str: =!!b!
  8. if "1!n:~50,1!!m:~50,1!" gtr "1!max!" (
  9. set max=!n:~50,1!!m:~50,1!
  10. set text=%%a
  11. )
  12. )
  13. echo !text!
  14. pause
复制代码

作者: zaixinxiangnian    时间: 2011-9-2 21:51

本帖最后由 zaixinxiangnian 于 2011-9-2 21:52 编辑

高手区啊,,,看了好久愣是没有看懂
  1. set m=0
  2.       call :1                  
  3. )
  4. echo %wang%
  5. pause
  6. goto :eof
  7. :1
  8.   if not "!ke1:~%m%,1!"=="" set /a m+=1&goto 1
  9.   if %m% gtr %n% set n=%m%&set wang=%ke%
  10.   goto :eof
复制代码
哪位高手有时间给句句解释下  set m=0 是不是每次累加呀。。。。。
作者: Seder    时间: 2011-9-14 18:40

加点分呗
  1. gawk "{str=$0;gsub(/ /,\"\",str);count=length(str);if(max<count){max=count;strOut=$0;}}END{print strOut}" test.txt
复制代码

作者: 尘丶    时间: 2015-9-13 12:35

  1. @echo off&setlocal enabledelayedexpansion
  2. for /f "tokens=1,2 delims=:" %%a in ('findstr /n . a.txt') do (
  3.     set str=%%b
  4.     set str=!str: =!
  5.     for /l %%c in (0,1,100) do (
  6.         set str2=!str:~%%c,1!
  7.         if not "!str2!"=="" set /a "#%%a+=1"&set "_%%a=%%b"
  8. )
  9. )
  10. for /f "tokens=1,2 delims==" %%a in ('set #') do set num=!num! %%b
  11. set num=!num:~1!
  12. for /l %%a in (1,1,100) do (
  13.     for %%b in (!num!) do (
  14. if %%a==%%b set shuzi=%%b
  15. )
  16. )
  17. for /f "tokens=1,2 delims==" %%a in ('set #') do (
  18. set zimu=%%a
  19. if %%b==!shuzi! set zimu=!zimu:~1!
  20. )
  21. call,echo;%%_!zimu!%%
  22. pause
复制代码
代码有点多
作者: 路过    时间: 2015-10-1 20:12

  1. @echo off&setlocal enabledelayedexpansion
  2. set w=0&set "e="
  3. for /f "tokens=*" %%i in (a.txt) do (set q=%%i
  4.   call :m !q: =!
  5.   set/a r=w-l
  6. if "!r:~0,1!"=="-" (set w=!l!&set e=%%i))
  7. echo;%e%
  8. pause&exit
  9. :m
  10. set m=%1&set l=0
  11. for /l %%i in (0,1,1024) do (if "!m:~%%i,1!"=="" (set/a l=%%i-1&goto :eof))
复制代码

作者: codegay    时间: 2016-5-2 04:05

  1. """
  2. python3
  3. 找出字符数最多的行
  4. 2016年5月2日 03:56:13 codegay
  5. """
  6. with open("a.txt") as f:
  7.     kv={''.join(r.split()).__len__():r for r in f}
  8.     print(kv[max(kv)])
  9.             
  10.             
复制代码

作者: qixiaobin0715    时间: 2021-3-3 11:07

参考3楼代码,这样效率要高些:
  1. @echo off
  2. set firstline=true
  3. set m=0
  4. setlocal enabledelayedexpansion
  5. for /f "delims=" %%a in (test2.txt) do (
  6.     set "str1=%%a"
  7.     set "str2=!str1: =!
  8.     if "%firstline%"=="true" (
  9.         set firstline=false
  10.         call :o
  11.     ) else (
  12.         for %%b in ("!m!") do if not "!str2:~%%b!"=="" call :o
  13.     )
  14. )
  15. echo %longestline%
  16. echo %m%
  17. pause
  18. goto :eof
  19. :o
  20. if not "!str2:~%m%!"=="" set /a m+=1&set longestline=%str1%&goto :o
  21. goto :eof
复制代码





欢迎光临 批处理之家 (http://bbs.bathome.net/) Powered by Discuz! 7.2