Board logo

标题: 【练习-019】批处理顺序排列文本内容 [打印本页]

作者: pusofalse    时间: 2008-8-31 14:51     标题: 【练习-019】批处理顺序排列文本内容

前些天在CN-DOS翻老帖,看到如此的一个题目,又加深了一点难度,有兴趣的来做下。
加分规则:
1.思路独特 5分
2.代码高效、通用 4分
3.技巧高超 4分
4.代码简洁 2分
5.完美代码 15分
题目如下:
a.txt内容:
  1. A111
  2. Assure
  3. Cons tant
  4. Smail
  5. A012
  6. Exa
  7. Explosive
  8. Weird
  9. Admission
  10. A077
  11. Chant
  12. Reli gious
  13. Praise
  14. Rhyming
  15. Parsley
  16. A034
  17. Faith
  18. Zealous
  19. Absorb
  20. Principle
复制代码
按照段落序号从小到大顺序排列,如下:
  1. A012
  2. Exa
  3. Explosive
  4. Weird
  5. Admission
  6. A034
  7. Faith
  8. Zealous
  9. Absorb
  10. Principle
  11. A077
  12. Chant
  13. Reli gious
  14. Praise
  15. Rhyming
  16. Parsley
  17. A111
  18. Assure
  19. Cons tant
  20. Smail
复制代码
每段的单词个数未知,在单词随机处有空格。
段落序号A之后的数字总是3位,若不够三位,则在前面加0表示。
A077,而不是A77。A034,而不是A34

[ 本帖最后由 pusofalse 于 2008-8-31 21:32 编辑 ]
作者: youxi01    时间: 2008-8-31 19:13


从小到大排列


这句话应该说清楚:按各段落文字第一列数字大小顺序排列!
如:....
作者: pusofalse    时间: 2008-8-31 19:16     标题: 回复 2楼 的帖子

谢谢指正,已经修改!
作者: terse    时间: 2008-8-31 20:02

先发个粗糙的 感觉可以精简
  1. @echo off&setlocal enabledelayedexpansion
  2. for /f "tokens=1* delims=:" %%i in ('findstr /n .* "1.txt"') do (
  3.     if "%%j"=="" (
  4.     for /f "tokens=1* delims=#" %%a in ("!str!") do (
  5.     set .%%a=%%a#%%b&set str=
  6.     ))
  7.     if defined str (set str=!str!#%%j)else set str=%%j
  8.     )
  9. for /f "tokens=1* delims=#" %%a in ("!str!") do set .%%a=%%a#%%b
  10. for /f "tokens=2 delims==" %%i in ('set .') do (
  11.     set str=%%i
  12.     set "str=!str:#=&echo.!"
  13.     call:lp
  14.     )
  15. pause&exit
  16. :lp
  17. echo %str%
  18. echo.
复制代码

再改就这样  没突破  下面继续吧
  1. @echo off&setlocal enabledelayedexpansion
  2. for /f "tokens=1* delims=:" %%i in ('findstr /n .* "1.txt"') do (
  3.     if not "%%j"=="" (if defined str (set str=!str!#%%j)else set str=%%j)else set .!str!=ok&set str=
  4.     )
  5.     set .!str!=ok
  6.     for /f "tokens=1 delims=.=" %%i in ('set .') do (
  7.     set str=%%i
  8.     set "str=!str:#=&echo.!"
  9.     call:lp
  10.     )
  11.     pause&exit
  12. :lp
  13. echo %str%
  14. echo.
复制代码

[ 本帖最后由 terse 于 2008-8-31 20:39 编辑 ]
作者: pusofalse    时间: 2008-8-31 20:14     标题: 回复 4楼 的帖子

刚看到这题时我感觉有点无从下手,但那只是被这题的外表所迷惑了而已。
感觉terse前辈考虑的有点过于复杂了。
作者: terse    时间: 2008-8-31 20:45

原帖由 pusofalse 于 2008-8-31 20:14 发表
刚看到这题时我感觉有点无从下手,但那只是被这题的外表所迷惑了而已。
感觉terse前辈考虑的有点过于复杂了。

试用sort  没成功
进了胡同

[ 本帖最后由 terse 于 2008-8-31 20:49 编辑 ]
作者: pusofalse    时间: 2008-8-31 20:57

我也用过sort,也没成功,可能还是思路不畅,同是用set来排的。
似乎都考虑到了这题只是合并第一个序号到第二个序号上一行的内容为一个变量,最后set自动排序。只是方法不同~
作者: batman    时间: 2008-8-31 22:12     标题: 来凑下热闹

  1. @echo off&setlocal enabledelayedexpansion
  2. for /f "tokens=1,2 delims=:" %%i in ('findstr /n .* a.txt') do (
  3.     if not defined flag (
  4.        set "a=%%j"&set "flag=a"
  5.        ) else (
  6.        if "%%j" neq "" (
  7.           call,set "_!a!=%%_!a!%% "%%j""
  8.           ) else (
  9.           set "flag="  
  10.        )
  11.     )
  12. )
  13. for /f "tokens=1,2 delims==" %%a in ('set _') do (
  14.     echo %%a
  15.     for %%i in (%%b) do echo %%~i
  16.     echo.
  17. )
  18. pause>nul   
复制代码

作者: batman    时间: 2008-8-31 22:13

晕,贴出来才发现和terse的如同一辙。。。
作者: huahua0919    时间: 2008-8-31 22:27

"只是合并第一个序号到第二个序号上一行的内容为一个变量"

不知道斑竹如何能够使一个回车能在set环境变量中存在?
作者: pusofalse    时间: 2008-8-31 22:56     标题: 回复 10楼 的帖子

兄所说的这种情况,恐怕是绝对不可能。或者误解我的意思了。
set var%n%=A012 Exa Explosive Weird Admission
for %%a in (!var%n%!) do echo %%a
作者: huahua0919    时间: 2008-8-31 23:03

好象段中的字也空格的吧,这样写不会将字分开了吗
作者: pusofalse    时间: 2008-8-31 23:05

是分开了,加个"闭合就可以了啊。
作者: pusofalse    时间: 2008-9-1 21:23

这题果真难倒了新手吗,期待新手解答出此题。以下,本人的解,期待更加简洁的解。
  1. @echo off&setlocal enabledelayedexpansion
  2. for /f "delims=" %%a in (a.txt) do (
  3.      set "var=%%a"
  4.      if "!var:~1,1!" leq "9" set "str=%%a"
  5.      call set ".!str!=%%.!str!%%"%%a" "
  6. )
  7. for /f "tokens=2 delims==" %%a in ('set .') do (
  8.      for %%i in (%%a) do echo %%~i
  9.      echo.
  10. )
  11. pause
复制代码

作者: flyinspace    时间: 2008-9-2 01:32

哦.看来只有另外想办法了....

利用skip吧..
  1. @echo off
  2. for /f "tokens=* " %%m in ('findstr /r "^A[0-9][0-9][0-9]$" 1.txt ^| sort /+1') do (
  3.         for /f "delims=: tokens=1,2 " %%i in ('findstr /n /r "^A[0-9][0-9][0-9]$" 1.txt') do if "%%j"=="%%m" echo %%m & call :loop %%i
  4.         echo.
  5.         )
  6. goto :exit
  7. :loop
  8.         for /f "skip=%1 tokens=* " %%n in (1.txt) do (
  9.                 echo %%n| findstr /r "^A[0-9][0-9][0-9]$">nul
  10.                 if not errorlevel 1 goto :EOF
  11.                 echo %%n
  12.                 )
  13.         goto :EOF
  14. :exit
  15. pause
复制代码

[ 本帖最后由 flyinspace 于 2008-9-3 14:59 编辑 ]
作者: batman    时间: 2008-9-2 20:10

原帖由 pusofalse 于 2008-9-1 21:23 发表
这题果真难倒了新手吗,期待新手解答出此题。以下,本人的解,期待更加简洁的解。@echo off&setlocal enabledelayedexpansion
for /f "delims=" %%a in (a.txt) do (
     set "var=%%a"
     if "!var:~1,1!" le ...

如就本题而言,这应该是最简洁的方案了,但如果要通用可能还是要用到set进行排序。
作者: flyinspace    时间: 2008-9-3 15:05

原帖由 batman 于 2008-9-2 20:10 发表

如就本题而言,这应该是最简洁的方案了,但如果要通用可能还是要用到set进行排序。


哦。。。那么文本的格式稍微变一下。

保持原题不变呢。

只是少了行距,和多了混乱的格式而已。
  1. A111
  2. Assure
  3. A12
  4. Cons tant
  5. Smail
  6. A012
  7. Exa
  8. Explosive
  9. Weird
  10. A12345
  11. Admission
  12. A077
  13. Chant
  14. Reli gious
  15. Praise
  16. Rhyming
  17. 32987
  18. Parsley
  19. A034
  20. Faith
  21. Zealous
  22. Absorb
  23. 24980
  24. Principle
复制代码

作者: pusofalse    时间: 2008-9-3 15:15     标题: 回复 17楼 的帖子

还是一样的解法吧,只不过要麻烦了。先找出哪些是序号,在序号前补位。
不知还有什么方法。
作者: flyinspace    时间: 2008-9-3 15:28

原帖由 pusofalse 于 2008-9-3 15:15 发表
还是一样的解法吧,只不过要麻烦了。先找出哪些是序号,在序号前补位。
不知还有什么方法。


只是看到你解决问题的方案比较儿戏。
不过也够简洁。

所以故意难为你一下。
作者: keen    时间: 2009-5-14 23:37

用了N多的FOR:
  1. @echo off&setlocal enabledelayedexpansion
  2. for /f "delims=" %%i in (a.txt) do (
  3.     set str=%%i
  4.     if "!str:~0,1!"=="A" (
  5.         set var=!str:~-3!
  6.         if !var! gtr 0 if !var! lss 999 set /a n+=1
  7. )
  8. call,set ".!n!=%%.!n!%%"%%i" "
  9. )
  10. for /f "tokens=2 delims==" %%i in ('set .') do (
  11.     for /f "tokens=1" %%a in ("%%i") do (
  12.         set hh=%%a&set num=!hh:~2,3!&set _!num!=%%i
  13. ))
  14. for /f "tokens=2 delims==" %%i in ('set _') do (
  15.     for %%b in (%%i) do echo %%~b
  16.     echo\
  17. )
  18. pause
复制代码

[ 本帖最后由 keen 于 2009-5-15 00:01 编辑 ]
作者: weichenxiehou    时间: 2011-1-1 19:59

  1. @echo off&setlocal enabledelayedexpansion
  2. for /f "usebackq" %%i in (`findstr "^A[0-9]*$" a.txt^|sort`) do (set /a num+=1&set "_!num!=%%i")
  3. for /l %%a in (1 1 %num%) do (
  4. call set "var=%%_%%a%%"
  5. for /f "delims=" %%j in (a.txt) do (
  6. if "%%j"=="!var!" (set flag=yes&set /a n=0) else (
  7. echo %%j|findstr "^A[0-9]*$">nul&&(set flag=&set /a n+=1&(if !n! equ 1 echo.))
  8. )
  9. if defined flag echo %%j
  10. )
  11. )
复制代码

[ 本帖最后由 weichenxiehou 于 2011-1-1 20:02 编辑 ]
作者: lengmoke    时间: 2021-9-23 16:09

本帖最后由 lengmoke 于 2021-9-23 17:06 编辑
  1. @echo off & setlocal EnableDelayedExpansion
  2. md temp
  3. for /f "tokens=1* delims=:" %%i in ('findstr /n .* "a.txt"') do (
  4.     if not "%%j"=="" ( set "str=%%j" & set "strs=!strs! !str: =+!" ) else ( md "temp\!strs!" & set "strs=" )
  5. )
  6. md "temp\!strs!"
  7. for /f "delims=" %%i in (' dir /b/on %cd%\temp ') do (
  8.     for %%j in (%%i) do ( set "str=%%j" & echo !str:+= !)
  9.     echo.
  10. )
  11. rd /q/s temp
复制代码

作者: qixiaobin0715    时间: 2021-9-24 12:14

试了试,发现还是和前辈们思路基本一致,就不好意思发出来了。




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