Board logo

标题: 【练习-056】随机产生规定范围内的日期 [打印本页]

作者: batman    时间: 2009-12-31 09:49     标题: 【练习-056】随机产生规定范围内的日期

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

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

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

作者: batman    时间: 2009-12-31 11:28     标题: 回复 2楼 的帖子

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

2、用call会大大降低代码效率,建议开启变量延迟不用call。
作者: neorobin    时间: 2009-12-31 12:31

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

[ 本帖最后由 neorobin 于 2009-12-31 12:39 编辑 ]
作者: wsjxwj    时间: 2009-12-31 13:01

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

作者: qzwqzw    时间: 2009-12-31 15:07

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


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

[ 本帖最后由 qzwqzw 于 2009-12-31 15:21 编辑 ]
作者: neorobin    时间: 2009-12-31 17:01

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

[ 本帖最后由 neorobin 于 2009-12-31 17:29 编辑 ]
作者: qzwqzw    时间: 2009-12-31 17:10

neorobin的思路有“漏洞”
闰年的2月1日没办法生成
作者: neorobin    时间: 2009-12-31 17:28     标题: 回复 8楼 的帖子

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

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

应改成
  1. set /a "day=!random!%%(28+^!(year%%4))+1"
复制代码

已作出修改, 并重新作了测试
作者: neorobin    时间: 2009-12-31 19:01

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

作者: neorobin    时间: 2010-1-2 08:35

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

作者: qzwqzw    时间: 2010-1-2 14:07

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

作者: a590687    时间: 2010-1-4 10:38

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

[ 本帖最后由 a590687 于 2010-1-4 10:51 编辑 ]
作者: a590687    时间: 2010-1-4 10:46

错大了.呀全31号了
作者: batman    时间: 2010-1-4 15:32

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

作者: batman    时间: 2010-1-5 08:49

现在突然想起来qzw原来是cn-dos的故人啊,我可真是有眼不识金镶玉啊。。。

关于此题个人感觉并无大的难点,生成的日期是三组随机数的组合,只要处理好

因月随机数取值的变化而导致的天随机数取值上限的变化就可以了,于是从这层

意义上来讲逻辑运算的拐的弯比if判断要多了,所以个人偏向于用if判断来处理这

样的情况。
作者: qzwqzw    时间: 2010-1-5 11:13

嗯,你说的对
逻辑运算的拐的弯比if判断要多

另外晒晒我的想法
要不是太苛刻的场合
我喜欢用我沙发上的代码
否则我喜欢找个第三方exe做个随机加法
有人用vbs加减我也不反对




欢迎光临 批处理之家 (http://bathome.net./) Powered by Discuz! 7.2