[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖
  terse在17楼的代码思路也非常不错,如果第二条for语句不使用type语句而直接sort的话,效率还可以稍有提升。

  23楼的思路正是我提到的 for /l+findstr+sort 方案,与17楼的方案比起来,在速度上差远了。

  就目前情况而言,17楼的方案应该是最通用、也是效率最高的了。
尺有所短寸有所长,学好批处理没商量;
考虑问题复杂化,解决问题简洁化。

心在天山,身老沧州。

TOP

set 变量法补 0 时也可以用其他符号如 +、# 或 $ 等。

总的想法与楼主一样,也是先 SET 变量(用来排序)再 FOR(用来输出)。

TOP

我最多就这思路了  貌似比上面麻烦  继续看看
  1. @echo off&setlocal enabledelayedexpansion
  2. (for /f "usebackq tokens=*" %%i in ("n.txt") do (
  3.     for %%j in (%%i) do echo %%j
  4. ))>tem
  5. for /l %%i in (1 1 4) do (
  6. if "!t!"=="" (set t=[0-9])else set t=[0-9]!t!
  7. for /f %%i in ('findstr "\<!t!\>" tem^|sort') do (
  8.     set/a n+=1,n%%=6
  9.     if !n! equ 0 (echo !var:~1! %%i&set "var=")else set var=!var! %%i
  10. )
  11. )
  12. if not "!var!"=="" echo !var:~1!
  13. pause
复制代码

TOP

海量数据用临时文件加findstr
少量数据用变量
我只能想到这样了。。

[ 本帖最后由 随风 于 2009-2-26 19:26 编辑 ]
技术问题请到论坛发帖求助!

TOP

用临时文件的话 我直接TYPE
FINDSTR 控制位数的话 好象用.的话的通配了  再想想
  1. @echo off&setlocal enabledelayedexpansion
  2. (for /f "usebackq tokens=*" %%i in ("n.txt") do (
  3.     for %%j in (%%i) do (
  4.         set "str=   %%j"
  5.         echo !str:~-4!
  6. )))>tem
  7. for /f "tokens=*" %%i in ('sort tem') do (
  8.   set/a n+=1,n%%=6
  9.   if !n! equ 0 (echo !var:~1! %%i&set "var=")else set var=!var! %%i
  10. )
  11. if not "!var!"=="" echo !var:~1!
  12. pause
复制代码

[ 本帖最后由 terse 于 2009-2-26 21:04 编辑 ]
1

评分人数

    • namejm: 很有技巧性,高。PB + 10

TOP

  for /l+findstr+sort 方案需要生成临时文件,临时文件是一行一条数据,然后想办法sort,需要用findstr的正则来控制要提取的数字的位数,如何控制参与sort的数字的位数是这个方案的关键,暂时就提示那么多,看看有没有人能写出成形的代码。

  呵呵,貌似这个题目弄成挑战赛了。
尺有所短寸有所长,学好批处理没商量;
考虑问题复杂化,解决问题简洁化。

心在天山,身老沧州。

TOP

for /l + findstr (有临时文件)
  1. @echo off
  2. setlocal EnableDelayedExpansion
  3. cd.>b.txt
  4. (for /f "delims=" %%a in ('type a.txt') do for %%i in (%%a) do echo %%i)>~a.txt
  5. (for /l %%a in (1 1 9999) do echo %%a)>~t.txt
  6. for /f %%a in ('findstr /rxg:~a.txt t.txt') do (
  7.   set var=!var! %%a
  8.   set /a n+=1
  9.   if !n!==6 (>>b.txt echo !var!&set var=&set n=)
  10. )
  11. (echo !var!)>>b.txt%不足6个数的部分%
  12. del ~a.txt ~t.txt
  13. start b.txt
复制代码
命令行参考:hh.exe ntcmds.chm::/ntcmds.htm
求助者请拿出诚心,别人才愿意奉献热心!
把查看手册形成条件反射!

TOP

set再for
  1. @echo off
  2. setlocal EnableDelayedExpansion
  3. cd.>b.txt
  4. for /f "delims=" %%a in ('type a.txt') do for %%i in (%%a) do set number=____%%i&set !number:~-5!=1
  5. for /f "delims=_=" %%i in ('set _^|sort') do (
  6.   set var=!var! %%i
  7.   set /a n+=1
  8.   set /a "i=1/(n/6)" 2>nul && (>>b.txt echo !var!&set var=&set n=)
  9. )
  10. (echo !var!)>>b.txt%不足6个数的部分%
  11. start b.txt
复制代码
命令行参考:hh.exe ntcmds.chm::/ntcmds.htm
求助者请拿出诚心,别人才愿意奉献热心!
把查看手册形成条件反射!

TOP

12楼的临时文件可省略
后面sort也可弃去 直接SET ..等同了
JM版的FINDSTR  总觉得是整行获取  那不是后面还要很多工作

[ 本帖最后由 terse 于 2009-2-26 17:38 编辑 ]

TOP

  做这个题目的时候,又想起了以前在其他论坛曾经帮别人解答过类似的题目,有位网友给出了一段十分经典的代码,用的是 for /l + findstr正则+sort 方案,只需要设置两个变量即可搞定,处理海量数据的速度只能用震惊来形容,处理顶楼的数据,排序部分花了不到两秒钟(机器配置:主频1.6G、内存512M、操作系统XP_SP3)。呵呵,先卖个关子,请大家继续。

  用顶楼的数据来测试我那个 for /l + findstr 的猜想,等了快10分钟都还没得到最终结果,看来cmd.exe对频繁调用某些命令可能有一些抑制机制,以防非正常的调用导致系统崩溃——当然,这只是我的一个猜想,各位可以当做是我在为自己可耻的失败寻找冠冕堂皇的理由^_^。
尺有所短寸有所长,学好批处理没商量;
考虑问题复杂化,解决问题简洁化。

心在天山,身老沧州。

TOP

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

心在天山,身老沧州。

TOP

我的思路  SET  后  FOR

TOP

回复 7楼 的帖子

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

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

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

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

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

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

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

心在天山,身老沧州。

TOP

返回列表