[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖
先说明下思路:
  此题确实是出给我们的一大难题,为什么这要说呢?楼主要求的是文本内所有超大数值的排序,
所有的数值都远远超过了cmd所能运算的最大数值,用常规的比较法都是行不通的这是难点之一;
第二这些数值是随机生成的且字符总数不定,甚至可能达到数行和数十行之长,如采用逐字符判断
的方法来确实行最大字符数,效率将会是此类方案所无法逾越的障碍;第三楼主要求不生成临时文
件,这对用findstr /o来获取行最大字符的方案来讲,无疑是锁上了大门。
  综上所述总结如下:
  代码要通用就要获取行最大字符数,一种方法是逐字符法,用逐字符法效率上就存在很大问题;
第二种方法是使用findstr /o一次性获取每行字符偏移量,再通过处理获得行最大字符数,效率上比
逐字符法是高多了,但因为单用findstr /o是不能获得文本行未行字符偏移量的,必须要对未行强加
回车,在不破坏原文件的情况下就要用到临时文件。
  而我们写代码时一般遵循四条原则:高效率、通用、简洁、尽量不生成临时文件,其中首要的
一条就是高效,其次是通用,至于简洁和有无临时文件都不是主要考虑因素,所以依此主次关系我
给出以下两种方案:
一、通用性差一点(数值字符都在一行内是绝对没问题的),效率高,代码简洁,无临时文件:
  1. @echo off&setlocal enabledelayedexpansion
  2. for /l %%i in (1,1,80) do set "kong=!kong!#"
  3. for /f %%i in (1.txt) do (
  4.      set "str=%%i%kong%"
  5.      set "a=!str:~,80!"
  6.      set "a=!a:%%i=!"
  7.      set "_!a!%%i=a"
  8. )
  9. for /f "delims==_" %%i in ('set _') do (
  10.      set "str=%%i"
  11.      echo !str:#=!
  12. )
  13. pause>nul
复制代码
当然也能通过修改80的值为更高来提高其通用性。
二、通用性极高,效率一般,生成临时文件,代码较复杂:
  1. @echo off&setlocal enabledelayedexpansion
  2. set "max=0"&set "a=0"
  3. for /f %%i in (1.txt) do echo %%i>>2.txt
  4. echo.>>2.txt
  5. for /f "tokens=1,2* delims=:" %%i in ('findstr /n /o .* 2.txt') do (
  6.     set /a n+=1,m=n-1
  7.     set "num=%%i"&set "_!n!=%%j"&set "#%%i=%%k"
  8.     if !m! gtr 0 set /a a=_!n!-_!m!-2
  9.     if !max! lss !a! set "max=!a!"
  10. )
  11. set /a num-=1
  12. for /l %%i in (1,1,%max%) do set "kong=!kong!#"
  13. for /l %%i in (1,1,%num%) do (
  14.     set "str=!#%%i!%kong%"
  15.     set "a=!str:~,%max%!"
  16.     call,set "a=%%a:!#%%i!=%%"
  17.     set ".!a!!#%%i!=a"
  18. )
  19. for /f "delims==." %%i in ('set .') do (
  20.     set "str=%%i"
  21.     echo !str:#=!
  22. )
  23. del /q 2.txt&pause>nul
复制代码

[ 本帖最后由 batman 于 2008-8-5 21:14 编辑 ]
***共同提高***

TOP

原帖由 pusofalse 于 2008-8-4 21:52 发表
这题在调试的时候才知道果真好麻烦啊~
感叹楼上的,高人~

谢谢兄弟指出,我的第二个代码已修正,其实3楼的代码并不通用,如下测试结果:
测试文本:
1.txt
  1. 29324200852651210028213071109630551685419682237192661910031596813525985
  2. 13919282422170532368385309906951146058242657993752114528415277712737232
  3. 28832607224652155316459166842936030363170611320231631619428405179384047
  4. 81217083066313894108553418317261065313629448519571101631624138851150746
  5. 13361717161263771422216995222461530385953272439225762679436096361638
  6. 99999999999999999999999999999999999999999999999999999999999999999999999
  7. 99999999999999999999999999999999999999999999999999999999999999999999999
  8. 99999999999999999999999999999999999999999999999999999999999999999999999
  9. 999999999999999999999999999999999999999999999999999999999
复制代码

运行3楼代码结果如下:
  1. 29448519571101631624138851150746133617171612637714222169952224615303859532724392
  2. 25762679436096361638
  3. 99999999999999999999999999999999999999999999999999999999999999999999999999999999
  4. 99999999999999999999
复制代码

而运行我第二楼第二个通用代码,结果如下:
  1. 99999999999999999999999999999999999999999999999999999999999999999999999999999999
  2. 99999999999999999999999999999999999999999999999999999999999999999999999999999999
  3. 99999999999999999999999999999999999999999999999999999999999999999999999999999999
  4. 99999999999999999999999999999
  5. 29324200852651210028213071109630551685419682237192661910031596813525985139192824
  6. 22170532368385309906951146058242657993752114528415277712737232288326072246521553
  7. 16459166842936030363170611320231631619428405179384047812170830663138941085534183
  8. 17261065313629448519571101631624138851150746133617171612637714222169952224615303
  9. 85953272439225762679436096361638
复制代码

ps:3楼的代码和我一楼的代码是一个意思,就是在前面补0,只不过我的是补足80位(针对数值字符在一
行的情况),而3楼的是补足100位(字符超过100位结果不正确了),而且好像我的代码效率还要稍高一
点。
***共同提高***

TOP

原帖由 pusofalse 于 2008-8-4 23:12 发表
没保存,害自己写了两遍。贴上来,免得再丢失。

@echo off&setlocal enabledelayedexpansion
set m=0
for /f "tokens=1,* delims=:" %%a in ('findstr/o .* 1.txt') do (
    set/a n+=1,l=n-1,y+=1
    set ...

使用管道又麻烦又影响效率,加个临时文件不是更好?
***共同提高***

TOP

返回列表