返回列表 发帖

【练习-056】随机产生规定范围内的日期

出题目的:
  考察大家对日期的计算能力
  巩固大家对随机取数的理解
加分原则:
  满分15分,视情况加分(以思路为重)
解题要求:
  要求代码高效、简洁、无临时文件
  请管理层的技术层暂不贴出代码,但可跟贴提示
题目如下:
  随机生成100个在2000-1-1至2009-12-31时间范围内的日期(可以重复),但要求是合理日期,如2003-2-29
2007-3-32都不是合理日期,也就是说无论代码运行多少次,都不会出现不合理的日期。
***共同提高***

我觉得至少应该对日期格式和返回方式应该有所要求吧

因为要求比较粗所以钻个空字
随机的年、随机的月、随机的日
加起来就是随机的日期了吧
不用管什么日期计算了
为了避免非法日期
所以舍弃了日的29、30、31这些日数
反正也没有一定要求有这些日
@echo off
for /l %%i in (1,1,100) do call :随机日期
goto :eof
:随机日期
set /a 随机年=%random% %% 10 + 2000
set /a 随机月=%random% %% 12 + 1
set /a 随机日=%random% %% 28 + 1
set 随机日期=%随机年%-%随机月%-%随机日%
echo.%随机日期%COPY
1

评分人数

    • batman: 参与了就是好的PB + 5

TOP

回复 2楼 的帖子

1、兄弟对题意中的随机概念理解有误,题目是要求随机生成100个2000-1-1至2009-12-31时间内的日期,也就
是说在这个时间范围内的日期都有可能出现,所以不能抛弃29、30、31这样的日子。

2、用call会大大降低代码效率,建议开启变量延迟不用call。
1

评分人数

    • qzwqzw: 呵呵,已经摆明车马是钻漏了,还这么较真 ...PB + 2
***共同提高***

TOP

@echo off & setlocal enabledelayedexpansion
for /l %%i in (1,1,100) do (
  set /a "year=!random! %% 10 +2000, month=!random! %% 12 +1, day=!random! %% 31 +1"
  if !month! equ 2 (
    set /a isLeap=year %% 4
    if !isLeap! equ 0 (set /a day=!random! %% 29 +1) else (set /a day=!random! %% 28 +1)
  ) else (
    for %%m in (4 6 9 11) do if %%m equ !month! set /a day=!random! %% 30 +1
  )
  echo %%i:!year!-!month!-!day!
)
pauseCOPY

[ 本帖最后由 neorobin 于 2009-12-31 12:39 编辑 ]

TOP

师傅我来交作业了,呵呵~这段代码我没有排除对2月的计算
@echo off&setlocal enabledelayedexpansion
for /l %%t in (1,1,100) do (echo 随机日期%%t为: &call :xx)
goto :eof
:xx
set /a n=%random%%%9
set i=200%n%
set /a j=%random%%%12+1
set /a k=%random%%%31+1
set aa=%i%-%j%-%k%
echo %aa%COPY

TOP

neorobin的思路太飘
看的我有点想飞起来


再我贴一个守规矩的
至于call和for的问题
满足要求就好
不需要太苛刻吧
主要是我觉得这种形式看着舒服 :-P
@echo off & setlocal EnableDelayedExpansion
for /l %%i in (1,1,100) do (
    call :随机日期 2000 10
    echo.!随机日期!
)
goto :eof
:随机日期 - 参数说明: %1 日期起始年份 %2 日期总年数
set /a 随机年=%random% %% %2 + %1
set /a 随机月=%random% %% 12 + 1
set /a 随机日=%random% %% 31 + 1
if 1%随机日% equ 131 (
    for %%m in (2 4 6 9 11) do if 1%随机月% equ 1%%m goto :随机日期
)
if 1%随机月% equ 12 (
    set /a "二月最大日=28+(^!(随机年 %% 4) & ^!(^!(随机年 %% 100)) | ^!(随机年 %% 400))"
    if !随机日! gtr !二月最大日! goto :随机日期
)
endlocal & set 随机日期=%随机年%-%随机月%-%随机日%COPY

[ 本帖最后由 qzwqzw 于 2009-12-31 15:21 编辑 ]
1

评分人数

    • batman: 逻辑运算用得好!PB + 5

TOP

借鉴 qzwqzw 逻辑非运算, 我的再省去一个 if 和一个 isLeap 变量, 楼主的题目条件只有 2000, 2004, 2008 这三个闰年, 所以不需完全的闰年判定法则,  只用对 4 取余判定就可以了.
@echo off & setlocal enabledelayedexpansion
for /l %%i in (1,1,100) do (
  set /a "year=!random!%%10+2000, month=!random!%%12+1, day=!random!%%31+1"
  if !month! equ 2 (
    set /a "day=!random!%%(28+^!(year%%4))+1"
  ) else (
    for %%m in (4 6 9 11) do if %%m equ !month! set /a day=!random!%%30+1
  )
  echo %%i:!year!-!month!-!day!  
)
pauseCOPY

[ 本帖最后由 neorobin 于 2009-12-31 17:29 编辑 ]

TOP

neorobin的思路有“漏洞”
闰年的2月1日没办法生成

TOP

回复 8楼 的帖子

原帖由 qzwqzw 于 2009-12-31 17:10 发表
neorobin的思路有“漏洞”
闰年的2月1日没办法生成

确实如此, 多谢指正,
set /a "day=!random!%%28+1+^!(year%%4)"COPY

应改成
set /a "day=!random!%%(28+^!(year%%4))+1"COPY

已作出修改, 并重新作了测试

TOP

让系统自己去判断生成的日期是否合法:
@echo off & chcp 936>nul
(set bakDate=%date:~0,4%-%date:~5,2%-%date:~8,2%) & set /a n=1001
:loop
set /a "year=%random%%%10+2000, month=%random%%%12+1, day=%random%%%31+1"
for /f %%e in ('echo. 2^>nul ^| date %year%-%month%-%day% ^| find "无法接受"') do if "%%e" neq "" goto loop
(set /a n+=1) & echo %n:~1%:%date%
if %n% leq 1100 goto loop
date %bakDate%
pauseCOPY
1

评分人数

    • batman: 思路独特,但效率有问题PB + 10

TOP

不用 if, 将逻辑进行到底
@echo off & setlocal enabledelayedexpansion
for /l %%i in (1,1,100) do (
  set /a "y=!random!%%10+2000, m=!random!%%12+1"
  set /a "f=^!(m-2), s=^!(m-4)|^!(m-6)|^!(m-9)|^!(m-11)"
  set /a "d=1+!random!%%(f*(28+^!(y%%4))+s*30+(^!f&^!s)*31)"
  echo %%i:!y!-!m!-!d!
)
pauseCOPY
2

评分人数

    • qzwqzw: 将逻辑进行到底就是物极必反了吧PB + 5
    • batman: 强人PB + 15

TOP

感觉减掉if对效率的提升不大
对可读性的降低倒是明显的
不过还是写了一个免if的版本
@echo off & setlocal EnableDelayedExpansion
for /l %%i in (1,1,100) do (
    call :随机日期 2000 10
    set/p=!随机日期!      <nul
)
goto :eof
:随机日期 - 参数说明: %1 日期起始年份 %2 日期总年数
for %%s in (1 3 5 7 8 10 12) do set days#%%s=31
for %%s in (4 6 9 11) do set days#%%s=30
set /a 随机年=%random% %% %2 + %1
set /a days#2="28+(^!(随机年 %% 4) & ^!(^!(随机年 %% 100)) | ^!(随机年 %% 400))"
set /a 随机月=%random% %% 12 + 1
set /a 随机日=%random% %% days#%随机月% + 1
set 随机月=0%随机月%&set 随机日=0%随机日%
endlocal & set 随机日期=%随机年%-%随机月:~-2%-%随机日:~-2%COPY
1

评分人数

TOP

@echo off&setlocal enabledelayedexpansion
for /l %%i in (1,1,100) do (
   set /a "y=!random! %%10+2000"
   set /a "m=!random! %%12+1"
        if !m! equ 2 (
           set /a "d=!random! %%28+1"&if "!y!%%4"=="0" (set/a "d=!danmon! %%29+1")
           ) else set /a "d=!random! %%31+1"
    echo %%i:!y!-!m!-!d!
)
pauseCOPY
if "!y!%%4"=="0" (set/a "d=!danmon! %%29+1")
::这句不知道行不行啊
::月份筛选怎么弄好COPY

[ 本帖最后由 a590687 于 2010-1-4 10:51 编辑 ]

TOP

错大了.呀全31号了

TOP

给出我最开始的解(想出题目后自己第一想到的思路):
@echo off&setlocal enabledelayedexpansion
set "days=31"
for %%a in (1 3 5 7 8 10 12 4 6 9 11) do (
    if %%a equ 4 set /a days-=1
    set /a _%%a=days
)
for /l %%a in (1,1,100) do (
    set /a a=!random!%%10,b=!random!%%12+1,ys=a%%4,_2=28
    if !ys! equ 0 set /a _2=29
    set /a c=!random!%%_!b!+1
    echo 200!a!-!b!-!c!
)
pause>nulCOPY
1

评分人数

    • qzwqzw: 嗯,符合简单实用的原则PB + 5
***共同提高***

TOP

返回列表