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

【练习-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 编辑 ]
***共同提高***

参考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
复制代码

TOP

  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.             
复制代码
去学去写去用才有进步。安装python3代码存为xx.py 双击运行或右键用IDLE打开按F5运行

TOP

  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))
复制代码
1

评分人数

TOP

  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
复制代码
代码有点多
心累~努力,为了美好的明天。

TOP

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

评分人数

TOP

本帖最后由 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 是不是每次累加呀。。。。。

TOP

在循环中非常高效的表驱动法:
  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
复制代码

TOP

本帖最后由 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
复制代码
说到底,知识就是那些,关键还是看怎么用(算法)。

TOP

32# qzwqzw


又忘了,已修改

TOP

怎么看怎么觉得这个修改后的代码仍然有问题
没有实测
就是觉得sort 既不用+%h% 也不用 /r
会将a.txt排序成什么样子
而第二个findstr 为什么还会用a.txt?
天的白色影子

TOP

本帖最后由 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. ...
复制代码

TOP

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
天的白色影子

TOP

代码看着顺畅多了
不需要实际测试与断点跟踪也能明白思路
给两个建议:
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了...

TOP

另外发现一个小问题
悄悄的告诉你
楼主的题目要求是获取不包含空格的字符数最多行
天的白色影子

TOP

返回列表