中国DOS联盟

-- 联合DOS 推动DOS 发展DOS --

联盟域名:www.cn-dos.net 论坛域名:www.cn-dos.net/forum
DOS,代表着自由开放与发展,我们努力起来,学习FreeDOS和Linux的自由开放与GNU精神,共同创造和发展美好的自由与GNU GPL世界吧!

中国DOS联盟论坛
现在时间是 2026-06-22 13:49
中国DOS联盟论坛 » DOS批处理 & 脚本技术(批处理室) » 随机显示5个不同的数 查看 6,592 回复 57
46 发表于 2007-01-06 15:28 ·  中国 河南 许昌 电信
金牌会员
★★★★
积分 3,687
发帖 1,467
注册 2005-08-08 12:00
20年会员
UID 44210
状态 离线
用“set /a randomloop=(%random%+%random%+%random%)%%100+1”增加随机性,也可以用“set /a randomloop=(%random%+%random%+%random%)/3%%100+1”

@echo off
set Max=100
set N=5

:start
cls
echo %time%
set Num=
set Tmp$=

:loop
set /a randomloop=(%random%+%random%+%random%)/3%%%Max%+1
for %%n in (%Tmp$%) do if "%randomloop%" == "%%n" goto loop
call set Tmp$=%%Tmp$%% %randomloop%
set /a Num+=1
set random_%Num%=%randomloop%
if %Num% LSS %N% goto loop

echo %Tmp$%
echo %time%
pause
goto start
exit
47 发表于 2007-01-06 23:47 ·  中国 北京 联通
银牌会员
★★★
努力做坏人
积分 1,185
发帖 438
注册 2006-08-28 12:00
19年会员
UID 61449
来自 北京
状态 离线
这几天看你们讨论这个帖子这么热闹,自己也忍不住试一把,以下代码测试100次没有出现问题,但不敢保证啊,还是请有心人测试一下才好


@echo off&setlocal enabledelayedexpansion
for /l %%a in (1;1;5) do (
set/a b=!random!%%99+1
call :pp !b!
)
goto :eof
:pp
if not defined %1 (set %1=a) else goto loop
echo %1
goto :eof
:loop
set/a b=!random!%%99+1
call :pp !b!

本帖最近评分记录 (共 1 条) 点击查看详情
评分人分数时间
lxmxn +4 2007-01-07 01:18
我今后在论坛的目标就是做个超级坏人!!!
48 发表于 2007-01-07 01:18 ·  中国 湖北 武汉 电信
版主
★★★★★
积分 11,386
发帖 4,938
注册 2006-07-23 17:10
19年会员
UID 59080
状态 离线

  9527 的代码测试通过,效果也不错,每次的数都很“随机”,加分。
49 发表于 2007-01-07 01:19 ·  中国 湖北 武汉 电信
版主
★★★★★
积分 11,386
发帖 4,938
注册 2006-07-23 17:10
19年会员
UID 59080
状态 离线
Originally posted by dikex at 2007-1-6 01:41:
嗯,有道理……
又一个猜想出现了^_^
可能时间只是产生时的其中一个参数,还与上一个随机数有关,而上一个经过某些放大差别以及和时间相关的迠...


  兄的发散思维令人佩服。
50 发表于 2007-01-07 01:26 ·  中国 广东 电信
荣誉版主
★★★★
batch fan
积分 5,226
发帖 1,737
注册 2006-03-10 00:38
20年会员
UID 51697
来自 成都
状态 离线
  那我也再帖一段代码,不用 defined 来控制重复值,速度有点慢:

@echo off
:begin
cls
set count=0

:loop
set /a num=%random%%%100+1
echo %str%|find " %num% ">nul&&goto loop
set str=%str% %num%
set /a count+=1
if %count% lss 5 goto loop
echo %str%
set str=
pause
goto begin

————————————————————————————————————
  原来 dikex 兄在43楼已经发过这样的代码,看来我是发重了。不过还是保留一下吧,感觉这个要稍微完善一点,没有和 dikex 兄争版权的意思。

[ Last edited by namejm on 2007-1-6 at 05:17 PM ]
尺有所短,寸有所长,学好CMD没商量。
考虑问题复杂化,解决问题简洁化。
51 发表于 2007-01-07 02:14 ·  中国 山东 济南 电信
社区乞丐
★★
此图片另存后死机
积分 -49
发帖 90
注册 2006-12-02 13:00
19年会员
UID 72412
性别 男
状态 离线
13楼产生重复的原因主要出在是取%random%的前两位.

把SET NO%%A=!RANDOM:~0,2! 换成SET /A NO%%A=!RANDOM! %% 100

就不成问题了.

其实对于这个问题已经没有什么好继续讨论的了,32楼的代码已经完全解释并解决了.

13楼的代码与其相比简直就是一个笑话....
我的网络笔记本.非联系本人请勿访问!http://w.vicp.net
52 发表于 2007-01-07 02:33 ·  中国 广东 电信
荣誉版主
★★★★
batch fan
积分 5,226
发帖 1,737
注册 2006-03-10 00:38
20年会员
UID 51697
来自 成都
状态 离线
Originally posted by tghksj at 2007-1-6 13:14:
其实对于这个问题已经没有什么好继续讨论的了,32楼的代码已经完全解释并解决了.

  同一问题,可以换用不同的思路来解决,最终是殊途同归,但精彩部分在于解决问题的过程而不是最终结果;或者根本得不到完美的结果,但是解决问题的过程却能给他人以启发。只要还有不同的解法,继续讨论下去还是有好处的。
尺有所短,寸有所长,学好CMD没商量。
考虑问题复杂化,解决问题简洁化。
53 发表于 2007-01-07 04:55 ·  中国 山东 济南 电信
社区乞丐
★★
此图片另存后死机
积分 -49
发帖 90
注册 2006-12-02 13:00
19年会员
UID 72412
性别 男
状态 离线
对32楼qzwqzw老师代码的剖析:


以0-3为范围,取0-3之间的随机。

代码修改如下:

@echo off
setlocal EnableDelayedExpansion

:: 初始化顺序数列
for /l %%i in (0,1,3) do (
set rnum%%i=%%i
)

:: 对数列进行随机交换
for /l %%i in (0,1,3) do (
set /a rnd=!random! %% 3
call set tmp=%%rnum!rnd!%%
set rnum!rnd!=!rnum%%i!
set rnum%%i=!tmp!
)

set rnum


逐行分析如下:

------------------------------------------
第一个FOR循环(0-3),四次

关键句:set rnum%%i=%%i
rnum0=0
rnum1=1
rnum2=2
rnum3=3
------------------------------------------
第二个FOR循环(0-3),四次

----------第一次:---------
关键句1: set /a rnd=!random! %% 3
运行结果: rnd=1
( !random! %% 3 的值为0-3间任意整数" 这里假设为1"
作用:将0-3间任意整数赋值给变量rnd )

关键句2: call set tmp=%%rnum!rnd!%%
运行结果: tmp=1
(因为此时 !rnd! 值为1 ,rnum!rnd!就是rnum1
此时 rnum1 值为1 ,所以%%rnum!rnd!%%值为1,所以tmp=1.
注意:rnum 并不是一个变量,这里只是一段字符串,与!rnd!组合后成为变量名
作用:和关键句1配合,将第一个循环的产生的任意一个变量的"值"赋给变量tmp)

关键句3: set rnum!rnd!=!rnum%%i!
运行结果: rnum1=0
(因为此时!rnd! 值为1,rnum!rnd!就是rnum1,
此时%%i 值为0,rnum%%i 就是rnum0,
此时!rnum0! 值为0,所以rnum1=0
注意:此时对第一个FOR循环中产生的变量的值进行了修改如下:
rnum0=0
rnum1=0
rnum2=2
rnum3=3
作用:和关键句1配合,随机抽取第一个FOR循环产生的变量名,并为其赋值为
"与第二个FOR循环,'此次循环次数'相对应的,第一个FOR循环内产生的变量的'值'")

关键句4: set rnum%%i=!tmp!
运行结果: rnum0=1
(此时对第一个FOR循环中产生的变量的值进行了修改如下:
rnum0=1
rnum1=0
rnum2=2
rnum3=3
看到这里就豁然开朗了,后面的3次循环也就不用再看了,
正是作者在原代码在第2个FOR循环前注释的:

作用: 与关键句1.2.3配合,对数列进行随机交换.

------------------------
当我在致力解决%random%出相同值的时候,
qzwqzw老师在第一个循环开始的时候就已经定义了其"不重复性"
目的值并不是%random%值,%random%只不过起到了随机互换的作用.......哎.........
qzwqzw老师每出一段代码我几乎都要看上20几个小时,
已至于我晚上睡觉在梦里满脑子都在想其算法机理,差距之大,难以想象...

[ Last edited by tghksj on 2007-1-6 at 03:57 PM ]
本帖最近评分记录 (共 1 条) 点击查看详情
评分人分数时间
9527 -11 2007-01-19 21:43
我的网络笔记本.非联系本人请勿访问!http://w.vicp.net
54 发表于 2007-01-07 05:47 ·  中国 广东 电信
荣誉版主
★★★★
batch fan
积分 5,226
发帖 1,737
注册 2006-03-10 00:38
20年会员
UID 51697
来自 成都
状态 离线
  实际上,qzwqzw 置换的模型是:假设有两个数A和B,现在要对它们的值互换,则设置一个临时变量tmp,先把A的值赋予tmp,然后,再把A的值设置为B的值,最后,再把B的值设置为tmp,这样,就实现了A和B这两个变量值的互换。

  因为最开始已经生成了rnd0、rnd1……rnd99共100个变量的值,这些变量的值是从0到99递增的;后一个 for 语句再用random来生成0到99的随机的rnd,以保证能随机抽取rnd0、rnd1……rnd99中的任一变量来置换,从而保证了数值的不重复性。整体的思路就是先顺后乱,以达到随机的目的。
尺有所短,寸有所长,学好CMD没商量。
考虑问题复杂化,解决问题简洁化。
55 发表于 2007-01-19 13:43 ·  中国 广西 玉林 博白县 电信
金牌会员
★★★★
积分 3,687
发帖 1,467
注册 2005-08-08 12:00
20年会员
UID 44210
状态 离线
qzwqzw 的随机方法不错

不过感觉一次要设置这么多的变量在只获取少量随机数时会造成运行效率下降:
:: 生成0-99之间的随机数列 R1
:: qzwqzw@bbs.cn-dos.net
:: 2007-01-04 23:03
@echo off
setlocal EnableDelayedExpansion

:: 初始化顺序数列
for /l %%i in (0,1,99) do (
set rnum%%i=%%i
)

:: 对数列进行随机交换
:loop
set time1=%time%
if not "%time1:~-2%" == "00" goto loop
cls
for /l %%i in (0,1,99) do (
set /a rnd=!random! %% 100
call set tmp=%%rnum!rnd!%%
set rnum!rnd!=!rnum%%i!
set rnum%%i=!tmp!
)

echo %rnum1% %rnum2% %rnum3% %rnum4% %rnum5%
echo %time1%
echo %time%
pause
goto loop

62 37 16 28 42
0:59:47.00
0:59:47.18
请按任意键继续. . .

@echo off
set Max=100
set N=5

:start
set time1=%time%
if not "%time1:~-2%" == "00" goto start
cls
set Num=
set Tmp$=

:loop
set /a randomloop=(%random%+%random%+%random%)/3%%%Max%+1
for %%n in (%Tmp$%) do if "%randomloop%" == "%%n" goto loop
call set Tmp$=%%Tmp$%% %randomloop%
set /a Num+=1
set random_%Num%=%randomloop%
if %Num% LSS %N% goto loop

echo %Tmp$%
echo %time1%
echo %time%
pause
goto start
exit

67 5 57 82 15
0:59:29.00
0:59:29.01
请按任意键继续. . .

[ Last edited by zh159 on 2007-1-19 at 01:01 AM ]
56 发表于 2007-01-19 22:27 ·  中国 广东 广州 天河区 电信
金牌会员
★★★★
一叶枝头,万树皆春
积分 2,564
发帖 1,127
注册 2006-12-25 22:57
19年会员
UID 74552
性别 男
状态 离线

for /l %%i in (1,1,5) do call :ccc %%i
echo %l1% %l2% %l3% %l4% %l5%
pause
exit
:ccc
set /a l%1=(((%time:~-1%+%1)*9-1)*(%time:~6,1%+%1)*(%time:~-2%+%1)*(%time:~7,1%+%1)*%1)%%100+%time:~7,1%+%1
57 发表于 2007-04-03 05:43 ·  中国 湖北 武汉 电信
中级用户
★★
scriptlover
积分 328
发帖 131
注册 2007-03-25 22:17
19年会员
UID 82910
性别 男
状态 离线
set random1=%random:~-2%
代码中%random:~-2%这个变两‘量有何含义?????????
58 发表于 2007-04-03 07:41 ·  中国 广东 广州 荔湾区 电信
银牌会员
★★★
积分 1,206
发帖 517
注册 2007-03-25 01:18
19年会员
UID 82819
性别 男
状态 离线
同时显示5个数字哦。

还是5位数??
知,不觉多。不知,乃求知
论坛跳转: