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

【练习-014】出给新手的数值排序加分题

出题目的:
        掌握任意数列之间的排序技巧
解题要求:
        代码通用、高效
        尽量简洁
        尽量不生成临时文件
加分规则:
        1 思路独特基准分5分
        2 代码高效、通用基准分4分
        3 技巧高超基准分3分
        4 代码简洁基准分2分
        5 完美代码加分15分
题目如下:
        给出任意一组数列,正序输出,如:
        3 2008 11 19 777 23 2014 453 789 51
        输出为:3 11 19 23 51 453 777 789 2008 2014
说明:
        不必考虑特大数,所给的数列中都是整数值。
心绪平和,眼藏静谧。

没明白LZ的意思呀,,
帮助别人是快乐
被人帮助是幸福

TOP

下午刚写了个快速排序,正好用上啦.冒泡就不写了.
cls&@echo off&setlocal enabledelayedexpansion
set "strings=3 2008 11 19 777 23 2014 453 789 51"
echo %strings%
set/a n=0
for %%i in (%strings%) do (
   
set/a n+=1
   
set num[!n!]=%%i
)
call :quicksort num 1 %n%
for /l %%i in (1,1,%n%) do echo !num[%%i]!

pause&goto:eof

:QuickSort
::code by dishuostec
::use call :quicksort arrary low high
set "ARR=%1"
set/a dep=0
call :QS %2 %3
goto:eof
:QS
set/a dep+=1,lTmpLow=%1,lTmpHi=%2,Low=%1,Hi=%2
if %Hi% leq %Low% set/a dep-=1&goto :eof
set/a lTmpMid=(Low+Hi)/2
call set/a vTempVal=%%%ARR%[!lTmpMid!]%%
:qsMainLoop
if !lTmpLow! leq !lTmpHi! (
   
:qsLoop1
   
call set/a vVal=%%%ARR%[!lTmpLow!]%%
   
if !vVal! lss !vTempVal! if !lTmpLow! lss !Hi! set/a lTmpLow+=1& goto qsLoop1
   
:qsLoop2
   
call set/a vVal=%%%ARR%[!lTmpHi!]%%
   
if !vTempVal! lss !vVal! if !Low! lss !lTmpHi! set/a lTmpHi-=1&goto qsLoop2
   
:qsSwap
   
if !lTmpLow! leq !lTmpHi! (
        
call set/a vTmpHold=%%%ARR%[!lTmpLow!]%%
        
call set/a %ARR%[!lTmpLow!]=%%%ARR%[!lTmpHi!]%%
        
set/a %ARR%[!lTmpHi!]=vTmpHold
        
set/a lTmpLow+=1,lTmpHi-=1
    )
goto qsMainLoop
)
set/a lTmpLow[%dep%]=lTmpLow,Hi[%dep%]=Hi
if %Low% lss %lTmpHi% call :QS %Low% %lTmpHi%
call set lTmpLow=%%lTmpLow[!dep!]%%&call set Hi=%%Hi[!dep!]%%
if %lTmpLow% lss %Hi% call :QS %lTmpLow% %Hi%
set/a dep-=1&goto :eof
1

评分人数

    • pusofalse: 除了简洁,所有要求都达到了。PB + 10
高手=发现问题^分析问题^解决问题

TOP

代码写的实在是繁杂。。。
***共同提高***

TOP

写这么长也很不错了

TOP

嫌代码长可以用冒泡法,但是数据量大的时候效率比快速排序低.
另外,我写的这两种排序都是通用模块,移植的拷过去就行.
cls&@echo off&setlocal enabledelayedexpansion
set "strings=3 2008 11 19 777 23 2014 453 789 51"
echo %strings%
set/a n=0
for %%i in (%strings%) do (
   
set/a n+=1
   
set num[!n!]=%%i
)
call :popsort num 1 %n%
for /l %%i in (1,1,%n%) do echo !num[%%i]!
pause&goto:eof

:PopSort
::code by dishuostec
::use call :PopSort arrary low highset "ARR=%1"
set /a PS_l=%3
for /l %%i in (%2,1,%3) do (
   
set/a PS_l-=1
   
for /l %%j in (%2,1,!PS_l!) do (
        
set/a PS_index2=%%j+1
        
call set PS_v1=%%%ARR%[%%j]%%&call set PS_v2=%%%ARR%[!PS_index2!]%%
        
if !PS_v1! gtr !PS_v2! set %ARR%[!PS_index2!]=!PS_v1!&set %ARR%[%%j]=!PS_v2!
    )
)
高手=发现问题^分析问题^解决问题

TOP

还是用补位效率高
  1. @echo off&setlocal enabledelayedexpansion
  2. set str=3 2008 11 19 777 23 2014 453 789 51
  3. for %%i in (%str%) do (
  4.     set str=0000000000%%i
  5.     set .!str:~-10! !random!=%%i
  6. )
  7. for /f "tokens=2 delims==" %%i in ('set .') do set/p=%%i <nul
  8. pause>nul
复制代码
1

评分人数

    • 523066680: 哈 从你一段精悍的代码能学到多样东西 荣幸 ...PB + 10

TOP

terse前辈,应该把这题留给新人做。^_^
心绪平和,眼藏静谧。

TOP

我的
~~~~~~~用了sort
  1. @echo off
  2. setlocal EnableDelayedExpansion
  3. set n=0
  4. for %%i in (3 2008 11 19 777 23 2014 453 789 51) do (
  5. set/a n+=1
  6. set str[!n!]=   %%i
  7. )
  8. for /l %%i in (1,1,%n%) do echo !str[%%i]:~-4!>>1.txt
  9. sort 1.txt
  10. set /p a=按回车键结束
  11. del 1.txt
复制代码
测试通过
1

评分人数

o(∩_∩)o...~~~
空间:http://hi.baidu.com/fair_jm
喜欢批处理的没事的话去逛逛哦~~

TOP

回复 9楼 的帖子

echo !str[%%i]:~-4! 这里出现了问题,如果是个5位数呢。
测试如下:
for /l %%a in (1 1 10) do set "var=!var!!random! "
for %%i in (%var%) do (
.......
......
你的代码就会出错了。还能再精简,也用不到临时文件。

[ 本帖最后由 pusofalse 于 2008-8-21 16:26 编辑 ]
心绪平和,眼藏静谧。

TOP


精简直接用 |sort 就可以了 我知道 但就不知道该加在哪~~呵呵
那个~ 可以用扩展的大一点 我这样做是为了符合题意o(∩_∩)o...
o(∩_∩)o...~~~
空间:http://hi.baidu.com/fair_jm
喜欢批处理的没事的话去逛逛哦~~

TOP

sort 1.txt无异于
(echo   123&echo 12345&echo    23)|sort
心绪平和,眼藏静谧。

TOP

@echo off
echo 没排前
echo 3 2008 11 19 777 23 2014 453 789 51
echo,
echo 排列后
for /f "tokens=1-10 delims= " %%a in ("3 2008 11 19 777 23 2014 453 789 51") do echo %%a %%c %%d %%f %%j %%h %%e %%i %%b %%g
pause>nul

版主这样行不???学批2天,瞎弄``哈哈

[ 本帖最后由 start 于 2008-8-21 21:21 编辑 ]
1

评分人数

忆往昔笑豺狼哭叱咤天地风云际望今朝笑贫不笑娼人民不敌人民币

TOP

来一个偏方 虽然显示不慢 但理论上效率不高 不介意吧 o(∩_∩)o 只是偏方
@echo off
for %%a in (3 2008 11 19 777 23 2014 453 789 51) do set _%%a=exist
for /l %%a in (1,1,3000) do (if defined _%%a call,set n=%%n%% %%a)
echo %n%
pause

[ 本帖最后由 523066680 于 2008-8-21 21:51 编辑 ]
1

评分人数

    • pusofalse: 跟我的方案一样,的确很偏。PB + 2

TOP

原帖由 terse 于 2008-8-21 14:01 发表
还是用补位效率高
…… set .!str:~-10! !random!=%%i……

这里random是否起着一定作用。

TOP

返回列表