[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖
哈哈,小楼兄摆明的是在出难题啊,经测算日期计算只能用32秒左右的时间,确实是个挑战。。。

[ 本帖最后由 batman 于 2008-10-19 09:21 编辑 ]
***共同提高***

TOP

抛砖了!!!

仅做到日期从当前开始输出:
测试文本生成代码:
  1. @echo off&for /l %%i in (1,1,50000) do echo %%i>>"ab cd.txt"
复制代码
解题代码:
  1. @echo off&setlocal enabledelayedexpansion
  2. set "t=%time%"&echo.>c.txt
  3. set /a year=%date:~,4%,month=1%date:~5,2%%%100,day=1%date:~8,2%%%100,yun=29
  4. for /f "usebackq delims=" %%i in ("ab cd.txt") do (
  5.     echo !year!-!month!-!day! %%i>>c.txt
  6.     set /a day-=1
  7.     if !day! equ 0 (
  8.        echo.>>c.txt
  9.        set /a month-=1
  10.        if !month! equ 0 (
  11.           set /a year-=1,month=12,day=31&call :lp1
  12.           ) else (
  13.           call :lp2
  14.        )
  15.     )
  16. )
  17. echo 程序开始时间为:%t%
  18. echo 程序结束时间为:%time%
  19. pause>nul&goto :eof
  20. :lp1
  21. set /a a=year%%4,b=year%%100,c=year%%400,yun=28
  22. if %b% equ 0 (
  23.    if %c% equ 0 set "yun=29"
  24.    ) else (
  25.    if %a% equ 0 set "yun=29"
  26. )
  27. goto :eof     
  28. :lp2
  29. for /f "tokens=%month%" %%a in ("1#31 2#%yun% 3#31 4#30 5#31 6#30 7#31 8#31 9#30 10#31 11#30 12#31") do (
  30.     for /f "tokens=2 delims=#" %%i in ("%%a") do set "day=%%i"
  31. )
复制代码
经pusofalse版主提醒修改部分代码后再测试(本人机子慢了),测试时间如下:
***共同提高***

TOP

日期反过来输出不是做不到,只是一时只想到设置变量的办法,但设置50000个变量就根本谈不上效率了。。。不知随风兄有何妙法?
***共同提高***

TOP

看了这段代码,人都要晕了。。。。我也想过用这种方法,但这样效率肯定是上不去的,因
为这样要进行100000次日期计算,其中还要进行很多次的判断,但另一种平常好用的设置
变量法实践中效率更低(变量数量太大了),所以一直未能达到小楼兄的要求。。。
用kip的方法可以将文本未行变成首行,但输出就整个是反过来的,即当前日期和未行成了第
一行,再用一次skip就可以按要求输出了,但这样既显得罗索,效率也达不到一分左右完成
这一要求,同时可能还要生成一次临时文件。。。
期待小楼兄的答案。。。
***共同提高***

TOP

终于将效率问题解决了,但代码确实难读了。。。
说明一下:先计算出文本的总行数,然后用渐近法计算出第一个日期(先算年再算月和日)
,然后再用for在按行读取数据时进行日期的累加和输出到新文本。
  1. @echo off&setlocal enabledelayedexpansion
  2. set "t=%time%"&echo.>c.txt
  3. rem 提出当前的年月日数值
  4. set /a year=%date:~,4%,month=1%date:~5,2%%%100,day=1%date:~8,2%%%100
  5. rem 设置变量
  6. for %%i in (31 29 31 30 31 30 31 31 30 31 30 31) do (
  7.     set /a num+=1&set "_!num!=%%i"
  8.     set "code1=!code1! %%i"&set "code2=!code2! !num!#%%i"
  9. )
  10. rem 获取文本总行数
  11. for /f "usebackq delims=" %%i in ("ab cd.txt") do set /a n+=1
  12. rem 计算并减去本年已过的天数
  13. set /a n=n-day
  14. for %%a in (%code1%) do (
  15.     if "!m!" neq "%month%" (
  16.        set /a n-=%%a,m+=1
  17.        ) else (
  18.        goto lp1
  19.    )
  20. )
  21. :lp1
  22. rem 计算初始年份
  23. set /a year-=1,n-=365
  24. set /a a=year%%4,b=year%%100,c=year%%400,yun=28,_2=28
  25. if %b% equ 0 (
  26.    if %c% equ 0 set /a n-=1,yun+=1,_2+=1
  27.    ) else (
  28.    if %a% equ 0 set /a n-=1,yun+=1,_2+=1
  29. )
  30. if %n% geq 0 goto lp1
  31. set "code1=!code1:29=%yun%!"&set "code2=!code2:29=%yun%!"
  32. rem 计算初始月份和日期
  33. for %%a in (%code2%) do (
  34.     for /f "tokens=1,2 delims=#" %%i in ("%%a") do (
  35.         set /a n+=%%j
  36.         if !n! geq 0 set /a month=%%i-1,day=%%j-n&goto next
  37.     )
  38. )
  39. :next
  40. rem 核心代码部分,读取文本内容并递加日期,输出到新文本
  41. for /f "usebackq delims=" %%i in ("ab cd.txt") do (
  42.     set /a n=day-_!month!
  43.     if !n! gtr 0 call :lp2
  44.     if !month! geq 10 (
  45.        if !day! geq 10 (
  46.           echo !year!年!month!月!day!日 %%i>>c.txt
  47.           ) else (
  48.           echo !year!年!month!月0!day!日 %%i>>c.txt
  49.        )
  50.        ) else (
  51.        if !day! geq 10 (
  52.           echo !year!年0!month!月!day!日 %%i>>c.txt
  53.           ) else (
  54.           echo !year!年0!month!月0!day!日 %%i>>c.txt
  55.        )
  56.     )
  57.     set /a day+=1
  58. )
  59. echo 开始时间:%t%
  60. echo 结束时间:%time%
  61. pause>nul&goto :eof
  62. :lp2
  63. rem 子程序:跨月、跨年的计算和判断
  64. echo.>>c.txt
  65. set /a month+=1,day=1
  66. if %month% equ 13 (
  67.    set /a year+=1,month=1,a=year%%4,b=year%%100,c=year%%400,_2=28
  68.    if !b! equ 0 (
  69.       if !c! equ 0 set "_2=29"
  70.       ) else (
  71.       if !a! equ 0 set "_2=29"
  72.    )
  73. )
复制代码

[ 本帖最后由 batman 于 2008-10-20 03:40 编辑 ]
***共同提高***

TOP

下面是我对自己16楼代码的测试结果:

但13秒多的速度,确实让人期待。。。
***共同提高***

TOP

返回列表