![Board logo](images/default/logo.gif)
标题: 挑战:批处理数字排序 [打印本页]
作者: 随风 时间: 2009-3-2 18:30 标题: 挑战:批处理数字排序
挑战:数字排序
关于数字排序的代码已经讨论过很多次了。
目前就本人所知道的大至有以下几种
1、冒泡法
此法应该算是目前效率最高的了。可以处理cmd范围内的任何数字及重复数字。
2、将需排序的数字设为变量名
此法不能处理负数、和重复的数字,适合对文本进行一次性排序,
但若对文本逐行处理时效率极不理想。(代码简洁)
3、先把位数补齐,再用sort命令排序
此法适合处理超大数及海量数据,适合对文本进行一次性排序,
但若对文本逐行处理效率更不理想。(代码复杂,需临时文件配合)
挑战:冒泡排序法
加分条件:功能齐全、效率高出冒泡法 10 分
功能齐全、效率高出冒泡法、代码简洁。满分 15 分
因个人电脑配置不一,所以请各位同时帖出 冒泡法运行时间和自己的代码运行时间。
前提:a.txt 内容为5000行 每行有10个随机数(cmd范围内的)可能有负数及重复数和0
要求:把a.txt每行的数字进行排序
例:a.txt 部分内容如下
- -12051 -8021 -14576 -7510 -4872 -6546 -31396 0 13961 0 13961
- -14912 13403 -2365 30009 31652 -25405 -13924 0 -1349 0 -1349
复制代码
要求 b.txt 如下
- -31396 -14576 -12051 -8021 -7510 -6546 -4872 0 0 13961 13961
- -25405 -14912 -13924 -2365 -1349 -1349 0 0 13403 30009 31652
复制代码
- @echo off&set "f="
- ::创建测试文件代码
- cd.>a.txt
- setlocal enabledelayedexpansion
- for /l %%a in (1 1 5000) do (
- set "a="
- for /l %%i in (1 1 6) do (
- set /a w=!random!%%2
- if !w! equ 0 (set f=-) else set "f="
- set a=!a! !f!!random!
- )
- set b=!f!!random!&set b=!w! !b! !w! !b!
- >>a.txt echo !a:~1! !b!
- )
- pause
复制代码
计算效率代码
将 time0.bat 保存在批处理当前目录或system32目录,方便测试代码运行时间
调用方法
变量 t 为代码运行的起始时间。
set t=%time%
call time0.bat %t% %time% ok
echo %oK%
pause
- :time0 计算时间差 (封装)
- @echo off&setlocal&set /a n=0&rem code 随风 @bbs.bathome.net
- for /f "tokens=1-8 delims=.: " %%a in ("%~1:%~2") do (
- set /a n+=10%%a%%100*360000+10%%b%%100*6000+10%%c%%100*100+10%%d%%100
- set /a n-=10%%e%%100*360000+10%%f%%100*6000+10%%g%%100*100+10%%h%%100)
- set /a s=n/360000,n=n%%360000,f=n/6000,n=n%%6000,m=n/100,n=n%%100
- set "ok=%s% 小时 %f% 分钟 %m% 秒 %n% 毫秒"
- endlocal&set %~3=%ok:-=%&goto :EOF
复制代码
测试冒泡法代码
- @echo off&echo 正在测试 冒泡法数字排序。。。。
- :: 测试冒泡法 cmd范围数 5000行 每行10个数
- :: 本机测试 耗时:0 小时 0 分钟 31 秒 36 毫秒
- :: 测试环境:xp-sp2 cpu AMD 3000+ 1.81 GHz 内存:1G
- set t=%time%
- setlocal enabledelayedexpansion
- echo.>nul 3>b.txt
- for /f "delims=" %%a in (a.txt) do (
- setlocal
- set a=0&set "str="
- for %%i in (%%a)do set /a a+=1,b=a-1&set "num!a!=%%i"
- for /l %%i in (1 1 !b!) do (set /a var=%%i+1
- for /l %%j in (!var! 1 !a!) do (
- set /a var1=!num%%i!,var2=!num%%j!
- if !var1! gtr !var2! (set num%%i=!var2!&set num%%j=!var1!)))
- for /l %%i in (1 1 !a!) do set "str=!str! !num%%i!"
- echo !str!
- endlocal
- )
- call time0 %t% %time% ok&echo.&echo !ok!
- echo.>nul 4>con
- start "" "notepad" b.txt
- exit
复制代码
作者: terse 时间: 2009-3-2 21:17
测试 我这里的冒泡 怎么和随风兄的相差一半时间
看不出问题在那里
0 小时 0 分钟 13 秒 36 毫秒
0 小时 0 分钟 27 秒 1 毫秒
作者: 随风 时间: 2009-3-2 21:25
0 小时 0 分钟 34 秒 69 毫秒
怎么会有这么大的区别?
作者: terse 时间: 2009-3-2 21:54
估计这里 set /a var1=!num%%i!,var2=!num%%j!
你去掉试 在下面直接判断
几个方法 都没它快
[ 本帖最后由 terse 于 2009-3-2 23:04 编辑 ]
作者: 随风 时间: 2009-3-5 10:13 标题: 回复 4楼 的帖子
terse 兄的是什么配置啊?这么快,我去掉这一行也是一样
你再试试我的这个代码看看,理论上应该要快些的。- @echo off
- set t=%time%
- setlocal enabledelayedexpansion
- echo.>nul 3>b.txt
- for /f "delims=" %%a in (a.txt) do (
-
- setlocal
- set "m="
- (for %%j in (%%a)do (set b=%%j&set "s="
- for %%i in (!m!)do (if %%j gtr %%i (
- set s=!s! %%i)else set s=!s! !b! %%i&set b=)
- set "m=!s! !b! "))&set "m=!m: = !"
- echo !m:~1,-1!
- endlocal
-
- )
- call :time0 %t% %time% ok&echo.&echo 测试排序 !ok!
- echo.>nul 4>con
- start "" "notepad" b.txt
-
- :time0 计算时间差 (封装)
- @echo off&setlocal&set /a n=0&rem code 随风 @bbs.bathome.net
- for /f "tokens=1-8 delims=.: " %%a in ("%~1:%~2") do (
- set /a n+=10%%a%%100*360000+10%%b%%100*6000+10%%c%%100*100+10%%d%%100
- set /a n-=10%%e%%100*360000+10%%f%%100*6000+10%%g%%100*100+10%%h%%100)
- set /a s=n/360000,n=n%%360000,f=n/6000,n=n%%6000,m=n/100,n=n%%100
- set "ok=%s% 小时 %f% 分钟 %m% 秒 %n% 毫秒"
- endlocal&set %~3=%ok:-=%&goto :EOF
复制代码
作者: shqf 时间: 2009-3-5 11:31
1楼的程序在我机上25秒左右,5楼的才14秒左右,快了许多,佩服啊。这是什么原理的排序方法呀?我搞了个插入排序的,竟然要10多钟,晕死!
[ 本帖最后由 shqf 于 2009-3-5 11:50 编辑 ]
作者: terse 时间: 2009-3-5 15:24
Re:随风兄:
这次快多了啊
测试排序 0 小时 0 分钟 15 秒 9 毫秒
下面代码测试貌似又可提高点哦- @echo off&setlocal enabledelayedexpansion
- set t=%time%
- echo.>nul 3>c.txt
- for /f "delims=" %%a in (a.txt) do (
- for %%i in (%%a) do set /a n+=1&set a!n!=%%i
- set /a c=n-1
- for /l %%i in (1,1,!c!) do (
- set /a b=%%i+1
- for /l %%j in (!b!,1,!n!) do (
- if !a%%i! gtr !a%%j! set/a a%%j=!a%%i!,a%%i=!a%%j!
- )
- )
- for /l %%i in (1,1,!n!) do set "var=!var! !a%%i!"
- echo !var:~1!&set var=&set n=
- )
- call :time0 %t% %time% ok
- echo.>nul 4>con
- start "" "notepad" c.txt
-
- :time0 计算时间差 (封装)
- @echo off&set /a n=0&rem code 随风 @bbs.bathome.net
- for /f "tokens=1-8 delims=.: " %%a in ("%~1:%~2") do (
- set /a n+=10%%a%%100*360000+10%%b%%100*6000+10%%c%%100*100+10%%d%%100
- set /a n-=10%%e%%100*360000+10%%f%%100*6000+10%%g%%100*100+10%%h%%100)
- set /a s=n/360000,n=n%%360000,f=n/6000,n=n%%6000,m=n/100,n=n%%100
- set "ok=%s% 小时 %f% 分钟 %m% 秒 %n% 毫秒"
- echo %ok:-=%&goto :EOF
复制代码
作者: terse 时间: 2009-3-5 15:33
对了 测试环境:xp-sp3 cpu Intel(R) Core(TM)2 E4400 @ 2.00GHz 内存:2*1G
作者: 随风 时间: 2009-3-5 20:31
确实是多了set /a var1=!num%%i!,var2=!num%%j!这一句,导致代码多运行了这一句,又是在for的最里层,所以效率低了,都是我画蛇添足。
上次测试不行也是因为我在U盘里测试的,写入速度特慢,,
作者: RuiIsRui 时间: 2009-8-2 22:03
你们的代码貌似有漏啊!
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 毫秒
作者: netbenton 时间: 2009-8-2 23:13
按照给出的数据,改成这样只要 10 秒 56
- @echo off&setlocal enabledelayedexpansion
- set t=%time%
- echo.>nul 3>c.txt
- for /f "tokens=1-10" %%0 in (a.txt) do (
- set/a "a1=%%0,a2=%%1,a3=%%2,a4=%%3,a5=%%4,a6=%%5,a7=%%6,a8=%%7,a9=%%8,a10=%%9"
- for /l %%i in (1,1,9) do (
- set /a b=%%i+1
- for /l %%j in (!b!,1,10) do (
- if !a%%i! gtr !a%%j! set/a a%%j=!a%%i!,a%%i=!a%%j!
- )
- )
- echo !a1! !a2! !a3! !a4! !a5! !a6! !a7! !a8! !a9! !a10!
- )
- call :time0 %t% %time% ok
- echo.>nul 4>con
- start "" "notepad" c.txt
-
- :time0 计算时间差 (封装)
- @echo off&set /a n=0&rem code 随风 @bbs.bathome.net
- for /f "tokens=1-8 delims=.: " %%a in ("%~1:%~2") do (
- set /a n+=10%%a%%100*360000+10%%b%%100*6000+10%%c%%100*100+10%%d%%100
- set /a n-=10%%e%%100*360000+10%%f%%100*6000+10%%g%%100*100+10%%h%%100)
- set /a s=n/360000,n=n%%360000,f=n/6000,n=n%%6000,m=n/100,n=n%%100
- set "ok=%s% 小时 %f% 分钟 %m% 秒 %n% 毫秒"
- echo %ok:-=%&goto :EOF
复制代码
欢迎光临 批处理之家 (http://bbs.bathome.net/) |
Powered by Discuz! 7.2 |