[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

【练习-015】批处理随机取值练习

出题目的:
        掌握利用random进行随机取值技巧
解题要求:
        代码通用、高效
        尽量简洁
        尽量不生成临时文件
加分规则:
        1 思路独特基准分5分
        2 代码高效、通用基准分4分
        3 技巧高超基准分3分
        4 代码简洁基准分2分
        5 完美代码加分15分
题目如下:
  已知有1-26与a-z的一一对应,如1对应a 10对应j 26对应z,要求用批处理
从1-26 a-z这52个值中(全视为值)随机抽取10个互不相同的值并显示出来,
注意如同1和a 24和x 26和z这样的取值均视为相同不合要求。      
解题限制:
        暂无限制。
------------------------------------------------------------------------------------------------
目前的最佳答案见:16楼本人的解

[ 本帖最后由 batman 于 2008-8-30 13:10 编辑 ]
***共同提高***

呵呵
你昨天不是做好了吗?
我这还有你写的代码。

TOP

这是题目 给大家锻炼的。并不是有了一种方法 就不用做题了

TOP

哈哈,恭喜if exist成为技术组成员了!!!
废话就不多说了,不知是不是这样?
  1. @echo off
  2. Setlocal Enabledelayedexpansion
  3. set "var1=a b c d e f g h i j  k  l  m  n  o  p  q  r  s  t  u  v  w  x  y  z"
  4. for /l %%a in (1 1 26) do (set "var2=!var2!%%a ")
  5. for %%a in (%var1%) do (set /a "nn+=1"&set "!nn!=%%a"&set "%%a=!nn!")
  6. echo %var1%&echo %var2%&echo.
  7. :lp
  8. set /a "bt=%random%%%26+1","aa=%random%%%2+1"
  9. for /f "tokens=%bt%" %%a in ("!var%aa%!") do (
  10.    if defined .%%a goto :lp
  11.    if defined .!%%a! goto :lp
  12.    set "ech=!ech! %%a"
  13.    set ".%%a=ok"&set ".!%%a!=ok"
  14. )
  15. set /a mm+=1
  16. if %mm% lss 10 goto :lp
  17. echo %ech%
  18. for %%a in (%var1%) do (set ".%%a="&set ".!%%a!=")
  19. set "mm=0"&set "ech="
  20. pause>nul&goto :lp
复制代码
1

评分人数

TOP

楼上的代码写得复杂且效率低,但答案还是对的,加分鼓励。
***共同提高***

TOP

  1. @echo off&setlocal enabledelayedexpansion
  2. for %%i in (a b c d e f g h i j k l n m o p q r s t u v w x y z) do set "letter=!letter! %%i"
  3. for /l %%a in (1 1 26) do set "num=!num! %%a"
  4. :loop
  5. set/a n=%random%%%26+1
  6. if defined .%n% goto loop
  7. set .%n%=a
  8. if defined a (set var=%letter%) else set var=%num%
  9. for /f "tokens=%n%" %%a in ("%var%") do set/p=%%a <nul
  10. if not defined a (set a=a) else set "a="
  11. set/a m+=1
  12. if %m% neq 10 goto loop
  13. pause>nul
复制代码

等看BATMAN兄的代码。

[ 本帖最后由 pusofalse 于 2008-8-25 14:34 编辑 ]
1

评分人数

    • batman: 好,就是效率还有点问题。PB + 10
心绪平和,眼藏静谧。

TOP

&&pusofalse版主代码已经比较完美了,就是在效率上还存在一点小问题,其实对于这种
随机取值的问题在取值基数和取值个数差值较大时(如从1-100中随机取10个不同的数)
使用if判断返回还是可以的,但一旦取值基数和取值个数差值小甚至为0时(如从1-100中
随机取100个不同的数)这种方法就解决不了问题了,所以对于此类问题个人建议使用乱序
来进行处理,下面就以从1-100中随机取100个不同的数为例给出代码:
  1. @echo off&setlocal enabledelayedexpansion
  2. for /l %%i in (1,1,100) do set "_!random!!random!!random!!random!=%%i"
  3. for /f "tokens=2 delims==" %%i in ('set _') do set /p=%%i <nul
  4. pause>nul
复制代码
2

评分人数

    • more: 好东西!!!PB + 10
    • pusofalse: 学习了!受益匪浅!技术 + 6
***共同提高***

TOP

将4楼及6楼的代码改一下,貌似4楼的效率要比6楼的高些喔.
必须要承认的是6楼的想法比我的好多了,呵呵...
但是用时却比我的多,不知为何...
4楼:
  1. @echo off
  2. Setlocal Enabledelayedexpansion
  3. set "var1=a b c d e f g h i j  k  l  m  n  o  p  q  r  s  t  u  v  w  x  y  z"
  4. for /l %%a in (1 1 26) do (set "var2=!var2!%%a ")
  5. for %%a in (%var1%) do (set /a "nn+=1"&set "!nn!=%%a"&set "%%a=!nn!")
  6. Rem echo %var1%&echo %var2%&echo.
  7. :lp1
  8. echo %time%
  9. :lp
  10. set /a "bt=%random%%%26+1","aa=%random%%%2+1"
  11. for /f "tokens=%bt%" %%a in ("!var%aa%!") do (
  12.    if defined .%%a goto :lp
  13.    if defined .!%%a! goto :lp
  14.    set "ech=!ech! %%a"
  15.    set ".%%a=ok"&set ".!%%a!=ok"
  16. )
  17. set /a mm+=1
  18. if %mm% lss 10 goto :lp
  19. for %%a in (%var1%) do (set ".%%a="&set ".!%%a!=")
  20. set "mm=0"
  21. echo %ech%&echo %time%
  22. set "ech="
  23. pause>nul&cls&goto :lp1
复制代码
6楼:
  1. @echo off&setlocal enabledelayedexpansion
  2. for %%i in (a b c d e f g h i j k l n m o p q r s t u v w x y z) do set "letter=!letter! %%i"
  3. for /l %%a in (1 1 26) do set "num=!num! %%a"
  4. :lp
  5. echo %time%
  6. :loop
  7. set/a n=%random%%%26+1
  8. if defined .%n% goto loop
  9. set .%n%=a
  10. if defined a (set var=%letter%) else set var=%num%
  11. for /f "tokens=%n%" %%a in ("%var%") do set "wow=!wow! %%a"
  12. if not defined a (set a=a) else set "a="
  13. set/a m+=1
  14. if %m% neq 10 goto loop
  15. for /l %%a in (1 1 26) do (set ".%%a=")
  16. set "m=0"
  17. echo %wow%&echo %time%
  18. set "wow="
  19. pause>nul&cls&goto :lp
复制代码
1

评分人数

TOP

兄的学习态度太好了。
测试了一下,兄的代码平均间隔在0.02秒之内,我的代码差不多是0.03s。
的确慢了,可能是用了if defined 的缘故

[ 本帖最后由 pusofalse 于 2008-8-25 15:34 编辑 ]
心绪平和,眼藏静谧。

TOP

各位也都发表啦,我的也放出来啦 偶的还是原来的样子
  1. @echo off&setlocal enabledelayedexpansion
  2. set /a a=0,act=0
  3. for %%a in (a b c d e f g h i j k l m n o p q r s t u v w x y z) do  (
  4. set /a a+=1
  5. set n!a!=%%a)
  6. :act
  7. set /a act+=1
  8. :act-1
  9.   set /a n=%random%%%27
  10.   if %n% equ 0 set n=1
  11.   if not defined _%n% (
  12.       if %random:~-1% lss 5 (set number%act%=%n%) else (set number%act%=!n%n%!)
  13.       set _%n%=exist
  14.   ) else (goto :act-1)
  15.   echo !number%act%!
  16. if %act% lss 10 goto :act
  17. pause
复制代码
再小小修改代码,测试获得字母Z的频数,用来测试前面的代码随机性是否良好
  1. @echo off&setlocal enabledelayedexpansion
  2. set /a a=0,act=0
  3. for %%a in (a b c d e f g h i j k l m n o p q r s t u v w x y z) do  (
  4. set /a a+=1
  5. set n!a!=%%a)
  6. set test=0
  7. :act
  8. set /a act+=1
  9.   set /a n=%random%%%27
  10.   if %n% equ 0 set n=1
  11.       if %random:~-1% lss 5 (set number%act%=%n%) else (set number%act%=!n%n%!)
  12.   if !number%act%! equ z (set /a test+=1)
  13. if %act% lss 520 goto :act
  14. echo,520次 有%test%次出现z
  15. pause
复制代码





----------------
本楼第一段代码出现概率不平衡问题,请参照11楼和13楼的说法

[ 本帖最后由 523066680 于 2008-8-25 20:58 编辑 ]

TOP

其实10楼的这部分代码可以这样写的
  1. set /a n=%random%%%27
  2. if %n% equ 0 set n=1
复制代码
  1. set /a n=%random%%%26+1
复制代码

TOP

原帖由 523066680 于 2008-8-25 15:34 发表
各位也都发表啦,我的也放出来啦 偶的还是原来的样子@echo off&setlocal enabledelayedexpansion
set /a a=0,act=0
for %%a in (a b c d e f g h i j k l m n o p q r s t u v w x y z) do  (
set /a a+=1
set  ...

必须要指出你的问题了:
  代码书写极不规范,基本忽略了代码的可阅读性和美观性,在充分发挥兄弟的特长的基础上还请在这方面多下点功夫。。。
***共同提高***

TOP

原帖由 more 于 2008-8-25 15:44 发表
其实10楼的这部分代码可以这样写的set /a n=%random%%%27
if %n% equ 0 set n=1set /a n=%random%%%26+1


我觉得不是可以那样写,而是应该那样写,否则出现1的概率比其他数都大了1倍。随机应该要求概率一样。
1

评分人数

TOP

原帖由 itrui 于 2008-8-25 17:53 发表


我觉得不是可以那样写,而是应该那样写,否则出现1的概率比其他数都大了1倍。随机应该要求概率一样。


啊 这位真够细心啊!谢谢各位的指教!我会好好努力的!

TOP

你说的,随机的概率应该相等。
那么你写为if %n% equ 0 set n=1
出现1的概率也会比其他数多一倍。
我觉得没有绝对的概率相等,底数的概率总会多于其他数。
心绪平和,眼藏静谧。

TOP

返回列表