返回列表 发帖

【练习-002】批处理查找字符数最多的文本行


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

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







[ 本帖最后由 batman 于 2008-7-27 23:58 编辑 ]
***共同提高***

参考3楼代码,这样效率要高些:
@echo off
set firstline=true
set m=0
setlocal enabledelayedexpansion
for /f "delims=" %%a in (test2.txt) do (
    set "str1=%%a"
    set "str2=!str1: =!
    if "%firstline%"=="true" (
        set firstline=false
        call :o
    ) else (
        for %%b in ("!m!") do if not "!str2:~%%b!"=="" call :o
    )
)
echo %longestline%
echo %m%
pause
goto :eof
:o
if not "!str2:~%m%!"=="" set /a m+=1&set longestline=%str1%&goto :o
goto :eofCOPY

TOP

"""
python3
找出字符数最多的行
2016年5月2日 03:56:13 codegay
"""
with open("a.txt") as f:
    kv={''.join(r.split()).__len__():r for r in f}
    print(kv[max(kv)])
            
            COPY
去学去写去用才有进步。安装python3代码存为xx.py 双击运行或右键用IDLE打开按F5运行

TOP

@echo off&setlocal enabledelayedexpansion
set w=0&set "e="
for /f "tokens=*" %%i in (a.txt) do (set q=%%i
  call :m !q: =!
  set/a r=w-l
if "!r:~0,1!"=="-" (set w=!l!&set e=%%i))
echo;%e%
pause&exit
:m
set m=%1&set l=0
for /l %%i in (0,1,1024) do (if "!m:~%%i,1!"=="" (set/a l=%%i-1&goto :eof))COPY
1

评分人数

TOP

@echo off&setlocal enabledelayedexpansion
for /f "tokens=1,2 delims=:" %%a in ('findstr /n . a.txt') do (
    set str=%%b
    set str=!str: =!
    for /l %%c in (0,1,100) do (
        set str2=!str:~%%c,1!
        if not "!str2!"=="" set /a "#%%a+=1"&set "_%%a=%%b"
)
)
for /f "tokens=1,2 delims==" %%a in ('set #') do set num=!num! %%b
set num=!num:~1!
for /l %%a in (1,1,100) do (
    for %%b in (!num!) do (
if %%a==%%b set shuzi=%%b
)
)
for /f "tokens=1,2 delims==" %%a in ('set #') do (
set zimu=%%a
if %%b==!shuzi! set zimu=!zimu:~1!
)
call,echo;%%_!zimu!%%
pauseCOPY
代码有点多
心累~努力,为了美好的明天。

TOP

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

评分人数

TOP

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

高手区啊,,,看了好久愣是没有看懂
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 :eofCOPY
哪位高手有时间给句句解释下  set m=0 是不是每次累加呀。。。。。

TOP

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

TOP

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

模仿3楼的算法,手动写一个。
@echo off & Setlocal EnableDelayedExpansion
set n=0
::本以为变量不定义,用时值就自动是零,这里不定义n,后面就会出错。
For /f "delims=" %%i in (a.txt) do (
Set "a=%%i"
Set a1=!a: =!
Set str=0
Call :hello
)
echo %max%
pause
Goto :eof
:hello
If Not "!a1:~%str%,1!"=="" Set /a str+=1 & Goto hello
::此句用来计算字符串长度
If %str% gtr %n% Set n=%str%&Set max=%a%
Goto :eofCOPY
说到底,知识就是那些,关键还是看怎么用(算法)。

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

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

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

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。
改进的思路是:
endlocal
for /f "tokens=1* delims=:" %%a in ('findstr /n a.txt^|findstr 1:') do set "long=%%b"
...COPY
3、没看到楼主要求是不含空格,不过好像在谁的代码中看到了"findstr /o"...
我的代码习惯可能比较明显,要么大量使用外部命令,要么一堆for嵌套+set,减少call和goto。如果碰到大文件,外部命令优势明显,但是若要进行更精细的筛选,那还是只好老老实实用for了...

TOP

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

TOP

返回列表