返回列表 发帖
哈哈,小楼兄摆明的是在出难题啊,经测算日期计算只能用32秒左右的时间,确实是个挑战。。。

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

TOP

抛砖了!!!

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

TOP

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

TOP

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

TOP

终于将效率问题解决了,但代码确实难读了。。。
说明一下:先计算出文本的总行数,然后用渐近法计算出第一个日期(先算年再算月和日)
,然后再用for在按行读取数据时进行日期的累加和输出到新文本。
@echo off&setlocal enabledelayedexpansion
set "t=%time%"&echo.>c.txt
rem 提出当前的年月日数值
set /a year=%date:~,4%,month=1%date:~5,2%%%100,day=1%date:~8,2%%%100
rem 设置变量
for %%i in (31 29 31 30 31 30 31 31 30 31 30 31) do (
    set /a num+=1&set "_!num!=%%i"
    set "code1=!code1! %%i"&set "code2=!code2! !num!#%%i"
)
rem 获取文本总行数
for /f "usebackq delims=" %%i in ("ab cd.txt") do set /a n+=1
rem 计算并减去本年已过的天数
set /a n=n-day
for %%a in (%code1%) do (
    if "!m!" neq "%month%" (
       set /a n-=%%a,m+=1
       ) else (
       goto lp1
   )
)
:lp1
rem 计算初始年份
set /a year-=1,n-=365
set /a a=year%%4,b=year%%100,c=year%%400,yun=28,_2=28
if %b% equ 0 (
   if %c% equ 0 set /a n-=1,yun+=1,_2+=1
   ) else (
   if %a% equ 0 set /a n-=1,yun+=1,_2+=1
)
if %n% geq 0 goto lp1
set "code1=!code1:29=%yun%!"&set "code2=!code2:29=%yun%!"
rem 计算初始月份和日期
for %%a in (%code2%) do (
    for /f "tokens=1,2 delims=#" %%i in ("%%a") do (
        set /a n+=%%j
        if !n! geq 0 set /a month=%%i-1,day=%%j-n&goto next
    )
)
:next
rem 核心代码部分,读取文本内容并递加日期,输出到新文本
for /f "usebackq delims=" %%i in ("ab cd.txt") do (
    set /a n=day-_!month!
    if !n! gtr 0 call :lp2
    if !month! geq 10 (
       if !day! geq 10 (
          echo !year!!month!!day!%%i>>c.txt
          ) else (
          echo !year!!month!0!day!%%i>>c.txt
       )
       ) else (
       if !day! geq 10 (
          echo !year!0!month!!day!%%i>>c.txt
          ) else (
          echo !year!0!month!0!day!%%i>>c.txt
       )
    )
    set /a day+=1
)
echo 开始时间:%t%
echo 结束时间:%time%
pause>nul&goto :eof
:lp2
rem 子程序:跨月、跨年的计算和判断
echo.>>c.txt
set /a month+=1,day=1
if %month% equ 13 (
   set /a year+=1,month=1,a=year%%4,b=year%%100,c=year%%400,_2=28
   if !b! equ 0 (
      if !c! equ 0 set "_2=29"
      ) else (
      if !a! equ 0 set "_2=29"
   )
)COPY

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

TOP

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

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

TOP

返回列表