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

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

心在天山,身老沧州。

TOP

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

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

TOP

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

TOP

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

TOP

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

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

心在天山,身老沧州。

TOP

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

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

评分人数

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

TOP

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

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

TOP

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

TOP

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

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

TOP

  terse在17楼的代码思路也非常不错,如果第二条for语句不使用type语句而直接sort的话,效率还可以稍有提升。

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

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

心在天山,身老沧州。

TOP

回复 21楼 的帖子

'type tem^|sort' 为何不写成  sort tem
技术问题请到论坛发帖求助!

TOP

原帖由 随风 于 2009-2-26 20:31 发表
'type tem^|sort' 为何不写成  sort tem

这就改  谢

TOP

忍不住,也发两个凑凑热闹。
代码一、
不生成临时文件,适合处理少量数据。可以处理重复数字。
@echo off
if "%~1"=="" (
  setlocal enabledelayedexpansion&set /a n=0
  for /f "tokens=* delims=0" %%a in ('%~s0 h^|sort') do (
     set /a n+=1,n=n%%6
     set /p=%%a <nul
if !n! equ 0 echo.
   )
  pause&exit
)
setlocal enabledelayedexpansion
for /f "usebackq tokens=*" %%i in ("a.txt") do (
   for %%j in (%%i) do set m=0000000000%%j&echo !m:~-10!
)
endlocal
goto :EOFCOPY
代码二、
需确定最高位是多少。
生成一个临时文件也可以,不过既然已经生成了临时文件,不防再多生成一个以提高效率。
因为 for /f + findstr 效率很低。
适合处理海量数据。
@echo off&setlocal enabledelayedexpansion
(for /f "usebackq tokens=*" %%i in ("a.txt") do (
    for %%j in (%%i) do echo %%j
))>tem
sort tem>tem2
cd.>tem
for /l %%a in (1 1 4) do (
   set num=.!num!
   findstr /x !num! tem2>>tem
)
for /f "delims=" %%a in (tem) do (
     set /a n+=1,n=n%%6
     set /p=%%a <nul
if !n! equ 0 echo.
)
echo.&pauseCOPY
1

评分人数

    • namejm: 好代码,一出就是两个。PB + 10
技术问题请到论坛发帖求助!

TOP

为23楼加点注释以便初学者阅读

@echo off
setlocal enabledelayedexpansion
::把原始数据转换成每行只有一个数字的形式
(for /f "usebackq tokens=*" %%i in ("a.txt") do (
  for %%j in (%%i) do (
    echo %%j
  )
))>tem
::分别对一位、二位、三位、四位数字进行sort排序
::这样的做的原因是sort排序时是按照字符ASCII逐位比较的
for /l %%i in (1 1 4) do (
  if "!t!"=="" (
    ::定义这样的变量是为了在后面的findstr正则表达式中匹配任意一位09之间的数字
    set t=[0-9]
  ) else (
    ::在后面的findstr正则表达式中分别匹配二位、三位、四位数字
    set t=[0-9]!t!
  )
  ::控制参与sort排序的数字位数
  ::在findstr正则表达式中<string>表示精确匹配
  ::结合外层for循环实现分别对一位、二位、三位、四位数字进行sort排序
  for /f %%i in ('findstr "\<!t!\>" tem^|sort') do (
    set /a n+=1
    ::对6取余是实现六列一行的关键
    set /a n%%=6
    if !n! equ 0 (
      echo !var:~1! %%i
      set "var="
    ) else (
      set var=!var! %%i
    )
  )
)
if not "!var!"=="" (
  echo !var:~1!
)COPY
我帮忙写的代码不需要付钱。如果一定要给,请在微信群或QQ群发给大家吧。
【微信公众号、微信群、QQ群】http://bbs.bathome.net/thread-3473-1-1.html
【支持批处理之家,加入VIP会员!】http://bbs.bathome.net/thread-67716-1-1.html

TOP

为21楼加点注释以便初学者阅读

@echo off
setlocal enabledelayedexpansion
::把原始数据转换成每行只有一个数字的形式
(for /f "usebackq tokens=*" %%i in ("a.txt") do (
  for %%j in (%%i) do (
    ::在每个数字的最左侧补上三个空格
    set "str=   %%j"
    ::截取补空格以后的字符串的最右侧四位
    ::最终的结果就是把所有数字全部补成四个字符(不足四位的在左侧补空格)
    ::这样的做的原因是sort排序时是按照字符ASCII逐位比较的
    echo !str:~-4!
  )
))>"%temp%\GridNum.txt"
::利用tokens=*忽略行首空格的特性来删除前面补的空格
for /f "tokens=*" %%i in ('sort "%temp%\GridNum.txt"') do (
  set /a n+=1
  ::对6取余是实现六列一行的关键
  set /a n%%=6
  if !n! equ 0 (
    echo !var:~1! %%i
    set "var="
  ) else (
    set var=!var! %%i
  )
)
if not "!var!"=="" (
  echo !var:~1!
)COPY
我帮忙写的代码不需要付钱。如果一定要给,请在微信群或QQ群发给大家吧。
【微信公众号、微信群、QQ群】http://bbs.bathome.net/thread-3473-1-1.html
【支持批处理之家,加入VIP会员!】http://bbs.bathome.net/thread-67716-1-1.html

TOP

返回列表