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

【练习-036】批处理将数值按要求排序

出题目的:
  1、通过练习掌握数值排序的几种方法
  2、通过练习掌握切分字符串的方法
加分原则:
  满分15分,视情形加分(以思路为重)
解题限制:
  版主级的暂请观看,但可做解题提示
题目如下:
  有a.txt(见一)内容为N列N行不等的4位内数值,通过批处理将所有数值从小到大进行排序,并按6个数值一行输出到b.txt(见二)。

  1. 4981 5487 2724 2419 4837 2218 37 19 2880 5521
  2. 9613 7292 7433 554 8287 1147 9516 5678 9760 3028
  3. 9220 5936 3580 6455 8116 9776 6246 1652 6390 6615
  4. 7855 7707 1850 4564 2454 4571 7330 8718 4499 5083
  5. 7683 3076 637 3644 9714 6080 9554 8250 5353 6692
  6. 4036 9590 4539 8156 7648 6738 8834 7033 4043 9729
  7. 7512 1299 1611 1054 9291 9948 7213 5882 6891 6149
  8. 1159 7604 1290 7426 8342 4907 7802 2285 6828 4547
  9. 940 4594 5470 3831 7949 3308 8553 5841 4532 6151
  10. 2048 4362 7137 6227 1843 2833 119 6124 6716 4435
  11. 6342 132 4637 4359 7482 632 8 35 9999 1023
复制代码


  1. 8 19 35 37 119 132
  2. 554 632 637 940 1023 1054
  3. 1147 1159 1290 1299 1611 1652
  4. 1843 1850 2048 2218 2285 2419
  5. 2454 2724 2833 2880 3028 3076
  6. 3308 3580 3644 3831 4036 4043
  7. 4359 4362 4435 4499 4532 4539
  8. 4547 4564 4571 4594 4637 4837
  9. 4907 4981 5083 5353 5470 5487
  10. 5521 5678 5841 5882 5936 6080
  11. 6124 6149 6151 6227 6246 6342
  12. 6390 6455 6615 6692 6716 6738
  13. 6828 6891 7033 7137 7213 7292
  14. 7330 7426 7433 7482 7512 7604
  15. 7648 7683 7707 7802 7855 7949
  16. 8116 8156 8250 8287 8342 8553
  17. 8718 8834 9220 9291 9516 9554
  18. 9590 9613 9714 9729 9760 9776
  19. 9948 9999
复制代码

[ 本帖最后由 batman 于 2009-2-25 20:31 编辑 ]
***共同提高***

嗯..数据.数量很大的时候用什么方法好呢?二分法应该是比较快的了,但是不知道速度能不能跟上...
for /f "delims=" %%a in ('%0') do (echo %%a)

TOP

周哥,我目前只想到这个简单且效率不高的方法。
  1. @echo off
  2. for /f "tokens=1-10" %%a in (a.txt) do (
  3. set/a _%%a=0,_%%b=0,_%%c=0,_%%d=0,_%%e=0,_%%f=0,_%%g=0,_%%h=0,_%%i=0,_%%j=0
  4. )
  5. for /l %%i in (1,1,9999) do (
  6. if defined _%%i call :output %%i
  7. )
  8. exit
  9. :output
  10. <nul set/p=%1 >>b.txt
  11. set/a n+=1
  12. if %n% equ 6 echo.>>b.txt&set/a n=0
  13. goto :eof
复制代码
1

评分人数

    • batman: 就本题的数据而言是完成了PB + 5

TOP

请注意a.txt是n列n行,就是不知道有几行几列,所以楼上的tokens=1-10不可取,同时这种代码的效率是很相当低的。
***共同提高***

TOP

原帖由 BBCC 于 2009-2-25 21:37 发表
嗯..数据.数量很大的时候用什么方法好呢?二分法应该是比较快的了,但是不知道速度能不能跟上...

兄弟把你的方法写出来看看吧
***共同提高***

TOP

我想知道三个答案:
一、是不是我每次出的题都难了点,让大家习惯性的望而生畏了?
二、是不是大家都不想通过解题这种快捷方式来得到提高了?
三、难道论坛除了版主、技术组、新手(新手在做新手题)就没有其他的会员了?
***共同提高***

TOP

  1. @echo off&setlocal enabledelayedexpansion
  2. >b.txt cd.
  3. for /f "usebackq delims=" %%i in (`more a.txt`) do (set "numbers_old=!numbers_old! %%i")
  4. for %%i in (%numbers_old%) do (
  5.   set number=0000%%i
  6.   set number=!number:~-4!
  7.   set _!number!=%%i
  8. )
  9. for /f "tokens=2 delims==" %%i in ('set _') do (
  10.   for %%j in (%%i) do set "numbers_new=!numbers_new! %%j"
  11. )
  12. for %%i in (%numbers_new%) do (
  13.   set /p=%%i <nul >>b.txt
  14.   set /a n+=1
  15.   if !n! equ 6 echo.>>b.txt&set /a n=0
  16. )
  17. start b.txt
  18. exit
复制代码
说明一下:为此题学习了随风的排序函数,也终于搞懂了这个函数。学习了他的思路,不要分数,凑个热闹、搞点人气而已。

[ 本帖最后由 shqf 于 2009-2-26 12:57 编辑 ]
1

评分人数

    • batman: 代码还可精简PB + 10

TOP

原帖由 batman 于 2009-2-26 10:07 发表 [img][/img]
我想知道三个答案:
一、是不是我每次出的题都难了点,让大家习惯性的望而生畏了?
二、是不是大家都不想通过解题这种快捷方式来得到提高了?
三、难道论坛除了版主、技术组、新手(新手在做新手题)就没有其他的 ...

人家要上学嘛...看这个周末有时间不...

不过也是要号召更多人来做这种题啊...
for /f "delims=" %%a in ('%0') do (echo %%a)

TOP

  如果原始数据中没有重复的数值,并且数值的位数是已知的,那么,可以考虑用 for /l 生成从1~N的递增序列,每生成一个数值,就用 findstr 在原始表中查询数据,我觉得这应该是最简洁最高效的办法。

  当然,如何用 findstr 来精确匹配每一列数值,还得想办法对原始数据做一番处理。至于需要如何处理,各位开动脑筋想一想吧^_^。
尺有所短寸有所长,学好批处理没商量;
考虑问题复杂化,解决问题简洁化。

心在天山,身老沧州。

TOP

我不赞同jm的意见,首先我声明了原始数据中数值是不等的(这在题目中可以看到),其次
采用for /l (1,1,n)+findstr的方法效率不是最高的,举个例子假如原始数据中只有
1,1000,1000000000这三个数据,那岂不是for要空循环1000000000-3次,我觉得设置变量
法是最快的,以上面的例子只要设置三个变量就行了,至于具体怎么处理,大家思考了。
1

评分人数

    • youxi01: 有道理,我向来不看好&quot;findstr&quot; ...PB + 2
***共同提高***

TOP

  我认为,对于排序的问题,并没有一个谁快谁慢的绝对方案,要具体问题具体分析。

  如果数据十分少,且范围十分大,用 for /l + findstr 的方法无疑是很浪费的做法。

  如果是大量的数据,并且数据范围很窄,那么, for /l + findstr 应该是比较有优势的,因为用 for /l 罗列数字序列的速度非常快,可以免去数值大小的比较这一步,比较耗时的操作都是花费在频繁地调用findstr来打开文本文件上面,这使得 for /l + findstr 方案的效率骤然降低;在这种情况下,我觉得如果换用其他的方案,还需要先正确提取每一个数值,然后遍历表中的数据,对取到的每一个数值在表中做一番比较,处理次数将呈几何级增长,即使通过优化算法,数值比较的次数仍然十分可观,比较保守的估计,比较次数应该不低于1+2+3+……+N 次(N为数字个数),再加上批处理中没有数组的设计,保存那些临时数据也是件麻烦的事情,综合起来考虑,我并不觉得其他的方法比 for /l + findstr 好到哪里去。当然,限于本人的学识,对排序算法粗通皮毛,不知道是否有更高效的算法存在。

  声明:以上言论未经实测验证,仅为本人的推理,正确与否,以实际测试结果为准。
尺有所短寸有所长,学好批处理没商量;
考虑问题复杂化,解决问题简洁化。

心在天山,身老沧州。

TOP

  1. @echo off
  2. setlocal EnableDelayedExpansion
  3. >1.txt cd.&>b.txt cd.
  4. for /f "usebackq delims=" %%i in (`more a.txt`) do (
  5.   for %%j in (%%i)do (
  6.     set "number=   %%j"
  7.     echo !number:~-4!>>1.txt
  8.   )
  9. )
  10. for /f "usebackq" %%i in (`sort 1.txt`) do (
  11.   set /p=%%i <nul >>b.txt
  12.   set /a n+=1
  13.   if !n! equ 6 echo.>>b.txt&set /a n=0
  14. )
  15. start b.txt
  16. del 1.txt
  17. exit
复制代码
哈,我再来一个。这样的题蛮有意思。

TOP

回复 7楼 的帖子

用不着临时文件。
在for的in里面用('set _^|sor')t就可以排序。

话说我第一反应就是把数字作为变量名的一部分来存储。
命令行参考:hh.exe ntcmds.chm::/ntcmds.htm
求助者请拿出诚心,别人才愿意奉献热心!
把查看手册形成条件反射!

TOP

我的思路  SET  后  FOR

TOP

  如果是 set 后再 for ,对付少量的数据确实是个很高效的算法;若楼主的意图是处理海量数据,那么,大量的变量将会撑满内存,好像场面壮观了点^_^。
尺有所短寸有所长,学好批处理没商量;
考虑问题复杂化,解决问题简洁化。

心在天山,身老沧州。

TOP

返回列表