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

挑战:批处理数字排序

挑战:数字排序
关于数字排序的代码已经讨论过很多次了。
目前就本人所知道的大至有以下几种
1、冒泡法
   此法应该算是目前效率最高的了。可以处理cmd范围内的任何数字及重复数字。
2、将需排序的数字设为变量名
   此法不能处理负数、和重复的数字,适合对文本进行一次性排序,
   但若对文本逐行处理时效率极不理想。(代码简洁)
3、先把位数补齐,再用sort命令排序
   此法适合处理超大数及海量数据,适合对文本进行一次性排序,
   但若对文本逐行处理效率更不理想。(代码复杂,需临时文件配合)
挑战:冒泡排序法
加分条件:功能齐全、效率高出冒泡法 10 分
          功能齐全、效率高出冒泡法、代码简洁。满分 15 分
因个人电脑配置不一,所以请各位同时帖出 冒泡法运行时间和自己的代码运行时间。
前提:a.txt 内容为5000行 每行有10个随机数(cmd范围内的)可能有负数及重复数和0
要求:把a.txt每行的数字进行排序
例:a.txt 部分内容如下
  1. -12051 -8021 -14576 -7510 -4872 -6546 -31396 0 13961 0 13961
  2. -14912 13403 -2365 30009 31652 -25405 -13924 0 -1349 0 -1349
复制代码

要求 b.txt 如下
  1. -31396 -14576 -12051 -8021 -7510 -6546 -4872 0 0 13961 13961
  2. -25405 -14912 -13924 -2365 -1349 -1349 0 0 13403 30009 31652
复制代码
  1. @echo off&set "f="
  2. ::创建测试文件代码
  3. cd.>a.txt
  4. setlocal enabledelayedexpansion
  5. for /l %%a in (1 1 5000) do (
  6.    set "a="
  7.    for /l %%i in (1 1 6) do (
  8.       set /a w=!random!%%2
  9.       if !w! equ 0 (set f=-) else set "f="
  10.       set a=!a! !f!!random!
  11.     )
  12.     set b=!f!!random!&set b=!w! !b! !w! !b!
  13.     >>a.txt echo !a:~1! !b!
  14. )
  15. pause
复制代码

计算效率代码
将 time0.bat 保存在批处理当前目录或system32目录,方便测试代码运行时间
调用方法
变量 t 为代码运行的起始时间。
set t=%time%
call time0.bat %t% %time% ok
echo %oK%
pause
  1. :time0  计算时间差 (封装)
  2. @echo off&setlocal&set /a n=0&rem code 随风 @bbs.bathome.net
  3. for /f "tokens=1-8 delims=.: " %%a in ("%~1:%~2") do (
  4. set /a n+=10%%a%%100*360000+10%%b%%100*6000+10%%c%%100*100+10%%d%%100
  5. set /a n-=10%%e%%100*360000+10%%f%%100*6000+10%%g%%100*100+10%%h%%100)
  6. set /a s=n/360000,n=n%%360000,f=n/6000,n=n%%6000,m=n/100,n=n%%100
  7. set "ok=%s% 小时 %f% 分钟 %m% 秒 %n% 毫秒"
  8. endlocal&set %~3=%ok:-=%&goto :EOF
复制代码

测试冒泡法代码
  1. @echo off&echo 正在测试 冒泡法数字排序。。。。
  2. :: 测试冒泡法 cmd范围数 5000行 每行10个数
  3. :: 本机测试 耗时:0 小时 0 分钟 31 秒 36 毫秒
  4. :: 测试环境:xp-sp2  cpu AMD 3000+  1.81 GHz  内存:1G
  5. set t=%time%
  6. setlocal enabledelayedexpansion
  7. echo.>nul 3>b.txt
  8. for /f "delims=" %%a in (a.txt) do (
  9.    setlocal
  10.    set a=0&set "str="
  11.    for %%i in (%%a)do set /a a+=1,b=a-1&set "num!a!=%%i"
  12.    for /l %%i in (1 1 !b!) do (set /a var=%%i+1
  13.    for /l %%j in (!var! 1 !a!) do (
  14.    set /a var1=!num%%i!,var2=!num%%j!
  15.    if !var1! gtr !var2! (set num%%i=!var2!&set num%%j=!var1!)))
  16.    for /l %%i in (1 1 !a!) do set "str=!str! !num%%i!"
  17.    echo !str!
  18.    endlocal
  19. )
  20. call time0 %t% %time% ok&echo.&echo !ok!
  21. echo.>nul 4>con
  22. start "" "notepad" b.txt
  23. exit
复制代码
技术问题请到论坛发帖求助!

测试 我这里的冒泡 怎么和随风兄的相差一半时间
看不出问题在那里
0 小时 0 分钟 13 秒 36 毫秒
0 小时 0 分钟 27 秒 1 毫秒

TOP

0 小时 0 分钟 34 秒 69 毫秒
怎么会有这么大的区别?
技术问题请到论坛发帖求助!

TOP

估计这里   set /a var1=!num%%i!,var2=!num%%j!
你去掉试  在下面直接判断
几个方法 都没它快

[ 本帖最后由 terse 于 2009-3-2 23:04 编辑 ]

TOP

回复 4楼 的帖子

terse 兄的是什么配置啊?这么快,我去掉这一行也是一样
你再试试我的这个代码看看,理论上应该要快些的。
  1. @echo off
  2. set t=%time%
  3. setlocal enabledelayedexpansion
  4. echo.>nul 3>b.txt
  5. for /f "delims=" %%a in (a.txt) do (
  6. setlocal
  7. set "m="
  8. (for %%j in (%%a)do (set b=%%j&set "s="
  9. for %%i in (!m!)do (if %%j gtr %%i (
  10. set s=!s! %%i)else set s=!s! !b! %%i&set b=)
  11. set "m=!s! !b! "))&set "m=!m:  = !"
  12. echo !m:~1,-1!
  13. endlocal
  14. )
  15. call :time0 %t% %time% ok&echo.&echo 测试排序 !ok!
  16. echo.>nul 4>con
  17. start "" "notepad" b.txt
  18. :time0  计算时间差 (封装)
  19. @echo off&setlocal&set /a n=0&rem code 随风 @bbs.bathome.net
  20. for /f "tokens=1-8 delims=.: " %%a in ("%~1:%~2") do (
  21. set /a n+=10%%a%%100*360000+10%%b%%100*6000+10%%c%%100*100+10%%d%%100
  22. set /a n-=10%%e%%100*360000+10%%f%%100*6000+10%%g%%100*100+10%%h%%100)
  23. set /a s=n/360000,n=n%%360000,f=n/6000,n=n%%6000,m=n/100,n=n%%100
  24. set "ok=%s% 小时 %f% 分钟 %m% 秒 %n% 毫秒"
  25. endlocal&set %~3=%ok:-=%&goto :EOF
复制代码
技术问题请到论坛发帖求助!

TOP

1楼的程序在我机上25秒左右,5楼的才14秒左右,快了许多,佩服啊。这是什么原理的排序方法呀?我搞了个插入排序的,竟然要10多钟,晕死!

[ 本帖最后由 shqf 于 2009-3-5 11:50 编辑 ]

TOP

Re:随风兄:
这次快多了啊  
测试排序 0 小时 0 分钟 15 秒 9 毫秒

下面代码测试貌似又可提高点哦
  1. @echo off&setlocal enabledelayedexpansion
  2. set t=%time%
  3. echo.>nul 3>c.txt
  4. for /f "delims=" %%a in (a.txt) do (
  5.     for %%i in (%%a) do set /a n+=1&set a!n!=%%i
  6.          set /a c=n-1
  7.          for /l %%i in (1,1,!c!) do (
  8.          set /a b=%%i+1
  9.          for /l %%j in (!b!,1,!n!) do (
  10.          if !a%%i! gtr !a%%j! set/a a%%j=!a%%i!,a%%i=!a%%j!
  11.         )
  12.     )
  13.     for /l %%i in (1,1,!n!) do set "var=!var! !a%%i!"
  14.     echo !var:~1!&set var=&set n=
  15. )
  16. call :time0 %t% %time% ok
  17. echo.>nul 4>con
  18. start "" "notepad" c.txt
  19. :time0  计算时间差 (封装)
  20. @echo off&set /a n=0&rem code 随风 @bbs.bathome.net
  21. for /f "tokens=1-8 delims=.: " %%a in ("%~1:%~2") do (
  22. set /a n+=10%%a%%100*360000+10%%b%%100*6000+10%%c%%100*100+10%%d%%100
  23. set /a n-=10%%e%%100*360000+10%%f%%100*6000+10%%g%%100*100+10%%h%%100)
  24. set /a s=n/360000,n=n%%360000,f=n/6000,n=n%%6000,m=n/100,n=n%%100
  25. set "ok=%s% 小时 %f% 分钟 %m% 秒 %n% 毫秒"
  26. echo %ok:-=%&goto :EOF
复制代码

TOP

对了 测试环境:xp-sp3  cpu Intel(R) Core(TM)2 E4400  @ 2.00GHz  内存:2*1G

TOP

确实是多了set /a var1=!num%%i!,var2=!num%%j!这一句,导致代码多运行了这一句,又是在for的最里层,所以效率低了,都是我画蛇添足。
上次测试不行也是因为我在U盘里测试的,写入速度特慢,,
技术问题请到论坛发帖求助!

TOP

你们的代码貌似有漏啊!

2,15,20,33,56,1,07,54,89,66,23,25,27,28,29,55,56,57,5,59,6,78,74,66,08,28,9,30,52,14,15,16,2,10,20,30,40,50,60,70,80,90,100,8,4,6,15,16,13,5,9

结果:

08 1 2 2 4 5 5 6 6 07 8 9 9 10 13 14 15 15 15 16 16 20 20 23 25 27 28 28 29 30 30 33 40 50 52 54 55 56 56 57 59 60 66 66 70 74 78 80 89 90 100

测试排序 0 小时 0 分钟 0 秒 40 毫秒
天行健  君子以自强不息

TOP

按照给出的数据,改成这样只要 10 秒 56
  1. @echo off&setlocal enabledelayedexpansion
  2. set t=%time%
  3. echo.>nul 3>c.txt
  4. for /f "tokens=1-10" %%0 in (a.txt) do (
  5.     set/a "a1=%%0,a2=%%1,a3=%%2,a4=%%3,a5=%%4,a6=%%5,a7=%%6,a8=%%7,a9=%%8,a10=%%9"
  6.     for /l %%i in (1,1,9) do (
  7.          set /a b=%%i+1
  8.          for /l %%j in (!b!,1,10) do (
  9.                  if !a%%i! gtr !a%%j! set/a a%%j=!a%%i!,a%%i=!a%%j!
  10.          )
  11.     )
  12.     echo !a1! !a2! !a3! !a4! !a5! !a6! !a7! !a8! !a9! !a10!
  13. )
  14. call :time0 %t% %time% ok
  15. echo.>nul 4>con
  16. start "" "notepad" c.txt
  17. :time0  计算时间差 (封装)
  18. @echo off&set /a n=0&rem code 随风 @bbs.bathome.net
  19. for /f "tokens=1-8 delims=.: " %%a in ("%~1:%~2") do (
  20. set /a n+=10%%a%%100*360000+10%%b%%100*6000+10%%c%%100*100+10%%d%%100
  21. set /a n-=10%%e%%100*360000+10%%f%%100*6000+10%%g%%100*100+10%%h%%100)
  22. set /a s=n/360000,n=n%%360000,f=n/6000,n=n%%6000,m=n/100,n=n%%100
  23. set "ok=%s% 小时 %f% 分钟 %m% 秒 %n% 毫秒"
  24. echo %ok:-=%&goto :EOF
复制代码

TOP

返回列表