Board logo

标题: 随机显示5个不同的数 [打印本页]

作者: 26933062     时间: 2007-1-4 16:12    标题: 随机显示5个不同的数

能不能一次显示出1-100随机的5位数,并且不能有重复的.
想了很久,也搜索了论坛里的大部分帖子,好像都没有同时显示5位数的,关键是还要不能重复,


不好意识,对不起各位了,看来我的表达能力确实有问题.
我的目的是  显示1-100的随机数,   一次同时显示5个 ,  并且显示的这5个数不能有重复的.这样说大家能理解了吗?


首先多谢各位的精彩答复,因本人的批处理水平实在太菜,有些高深的答复不太看的懂,所以若有错误的评价还请见谅.....................
1, 6楼的答复基本符号要求,但多次使用时偶而会出现死循环现象,不知什么原因.
2, 13楼的虽没有重复现象,但每次运行后的第一位数总是相同,总觉略有不妥之处.
3, 26楼的虽然也可用,但是觉得过于呆板,(对不起,可能用词不当,但想不出更婉转的词了,见谅!)比如我想显示6位或7,8,9..........位就太麻烦了,其实我的本意是先要求输入随机数的最大值,再输入显示的位数.
4, 个人感觉(从思路上来说)32楼的应该是最理想的,但可惜我看不懂,而32楼的这位兄弟又没把代码按要求写完,(一次显示了100个).
5, 我认为33楼的代码应该是最好的了,从代码上看,应该是绝对没重复,而且很灵活,只是不知道会不会出现他们说的效率低,和死循环.目前运行状况良好.[/
size]

不好意识 版主 经反复测试,你6楼的方法没问题,只是会出现死循环,可能是测试的方法太多了,搞错了对象,对不起了.  在42楼修改后的方法我认为以接近完美,真是条条大路通罗马,好方法太多了,批处理真是对人思路的挑战.

[ Last edited by 26933062 on 2007-1-6 at 10:07 PM ]
作者: a9319751     时间: 2007-1-4 20:42
5个?5位?
1-100 有5位
作者: zh159     时间: 2007-1-4 22:17
5随机个1-99

1:
@echo off
:loop
cls
set random1=%random:~-2%

:loop2
set random2=%random:~-2%
if "%random2%" == "%random1%" goto loop2

:loop3
set random3=%random:~-2%
if "%random3%" == "%random1%" goto loop3
if "%random3%" == "%random2%" goto loop3

:loop4
set random4=%random:~-2%
if "%random4%" == "%random1%" goto loop4
if "%random4%" == "%random2%" goto loop4
if "%random4%" == "%random3%" goto loop4

:loop5
set random5=%random:~-2%
if "%random5%" == "%random1%" goto loop5
if "%random5%" == "%random2%" goto loop5
if "%random5%" == "%random3%" goto loop5
if "%random5%" == "%random4%" goto loop5

echo %random1% %random2% %random3% %random4% %random5%
pause
goto loop
2:
@echo off
:Start
cls
call :loop 1
call :loop 2
call :loop 3
call :loop 4
call :loop 5

echo %random1% %random2% %random3% %random4% %random5%
pause
set Tmp_=
goto :Start

:loop
set randomloop=%random:~-2%
for %%n in (%Tmp_%) do if "%randomloop%" == "%%n" goto loop
set random%1=%randomloop%
call set Tmp_=%%Tmp_%% %randomloop%
goto :eof
[ Last edited by zh159 on 2007-1-4 at 10:09 AM ]
作者: youxi01     时间: 2007-1-4 23:45
来凑个“热闹”
@echo off
setlocal enabledelayedexpansion
set /a a=1

:test
    set /a _num!a!=%random:~-2%
    if not defined !_num%a%!  set /a a+=1
    if !a! LSS 6 goto :test

echo %_num1% %_num2% %_num3% %_num4% %_num5%

pause>nul

作者: namejm     时间: 2007-1-5 01:52
  楼主的表达有问题,看了半天还不知道究竟是要生成1-99个不同的随机5位数还是在1-99中随机显示5个不同的数,请楼主表达清楚。
作者: namejm     时间: 2007-1-5 02:16
  看了4楼的代码,推测 youxi01 的本意是想显示5个 1-100 之间(不包含100)不同的随机数,但是代码是有问题的:%a% 是 1-5 的数,用 if not defined 来判断 num%a% 这个变量是否被定义过,执行的结果始终是没有定义过。

  按照4楼的思路修改代码如下:
@echo off
set count=0

:loop
set /a num=%random%%%99+1
if not defined num%num% (
    set num%num%=%num%
    set /a count+=1
    call echo %%num%%
)
if %count% lss 5 goto loop

pause>nul
——————————————————————————————————————
  如果循环调用这段代码,在第20次的时候会陷入死循环,具体情况请看16楼的描述,原因分析请看41楼,解决问题的代码请看42楼。

[ Last edited by namejm on 2007-1-6 at 05:03 PM ]
作者: tghksj     时间: 2007-1-5 03:05
怀疑自己的理解能力和楼主表达能力

是5个 还是5位? 5个 1-100 如下:
@ECHO %dbg% OFF
setlocal ENABLEDELAYEDEXPANSION

FOR /L %%A IN (1,1,5) DO ECHO !RANDOM:~-2!

作者: namejm     时间: 2007-1-5 03:33
  发现很多人都忽略了这样一个细节:%random:~-2% 有可能取到 00 这样的字符串,set /a num=%random:~-2% 虽然可以把 00 字符串数值化,变成0,但是,0却并不是楼主所想要的。
作者: tghksj     时间: 2007-1-5 04:30
那OK,
%random:~-2%不行就%random:~0,2%

保证前面没0
@ECHO %dbg% OFF
setlocal ENABLEDELAYEDEXPANSION

FOR /L %%A IN (1,1,5) DO ECHO !RANDOM:~0,2!

作者: ccwan     时间: 2007-1-5 04:36
取得的5个数中有相同的算不算?
作者: namejm     时间: 2007-1-5 04:41
  按照楼主的说法,5个数中不能出现相同的数。
作者: ccwan     时间: 2007-1-5 04:43
目前9楼的已发现有这种情况。
作者: tghksj     时间: 2007-1-5 06:18
OK!!!嵌套递归! 这下不重复了吧???呵呵
@ECHO %dbg% OFF
setlocal ENABLEDELAYEDEXPANSION
SET T=1

:PR
FOR /L %%A IN (%T%,1,5) DO (SET NO%%A=!RANDOM:~0,2! & SET /A H=%%A-1 & IF !H! GTR -1 (
FOR /L %%B IN (!H!,-1,1) DO (IF !NO%%A!==!NO%%B! (SET T=%%A & CALL :PR !T! & GOTO :EOF)))&ECHO !NO%%A!)
[ Last edited by tghksj on 2007-1-4 at 06:11 PM ]
作者: tghksj     时间: 2007-1-5 06:44
我晕~~我傻了,怎么没想起 if not defined
晕晕晕晕晕晕晕晕晕晕晕晕晕晕晕
@ECHO %dbg% OFF
setlocal ENABLEDELAYEDEXPANSION
CLS
SET T=1

:PR
FOR /L %%A IN (%T%,1,5) DO (
         SET NO%%A=!RANDOM:~0,2!
         IF DEFINED !NO%%A! (SET T=!%%A! & GOTO :PR)
         ECHO !NO%%A!
                            )
咦?????????不好使?????????????还是有重复的??!
高人解释下..............

暂时只有13楼可以了....

[ Last edited by tghksj on 2007-1-4 at 05:53 PM ]
作者: namejm     时间: 2007-1-5 06:58
  看了14楼的代码,发现里面并没有控制随机数是否重复的语句,多测试几次之后,就会发现有重复数值出现,建议参考一下我在6楼帖出来的代码。
作者: namejm     时间: 2007-1-5 07:07
  发现了一个不可思议的现象:如果在6楼代码首尾的合适位置添加跳转语句和接收标签,从而使代码循环执行的话,则执行到第20次之后,就会只出现前4个数值,然后程序开始在 :loop 和 if %count% lss 5 goto loop 这个循环体内疯狂运行,第5个数值一直不能出现。嘿嘿,怪事。

————————————————————————————————
  原因分析请看41楼,解决问题的代码请看42楼。

[ Last edited by namejm on 2007-1-6 at 04:58 PM ]
作者: tghksj     时间: 2007-1-5 07:18
没什么好奇怪的,你没加 setlocal

13楼的代码已经可以解决问题了只是还有

请问 namejm 老师

%random%%%99

是什么意思啊???

[ Last edited by tghksj on 2007-1-4 at 06:26 PM ]
作者: namejm     时间: 2007-1-5 07:27
  表示用一个随机数除以99,然后取余数,也就是数学上所说的模运算。

  13楼的代码确实不会出现重复值,但是,要出现一位数的几率就太小了,简直是千年等一回呢^_^。
作者: youxi01     时间: 2007-1-5 07:35


  Quote:
Originally posted by namejm at 2007-1-5 02:16 AM:
  看了4楼的代码,推测 youxi01 的本意是想显示5个 1-100 之间(不包含100)不同的随机数,但是代码是有问题的:%a% 是 1-5 的数,用 if not defined 来判断 n ...

我要的效果就是要它没有定义过,要是定义过了,那不就重复了嘛!
作者: tghksj     时间: 2007-1-5 07:36
谢谢老师的说明.

13楼只有当 %random% LSS 10 的时候才会有 1位数 呵呵 几率确实很小的.

6楼的代码确实不知道什么原因......

多次执行之后就不能使用了????!!

%count% 永远==0了...????奇怪哦

清空count 后 setlocal 也不管用了...纳闷....

等高人解释一下了......

[ Last edited by tghksj on 2007-1-4 at 06:39 PM ]
作者: namejm     时间: 2007-1-5 07:57


  Quote:
Originally posted by youxi01 at 2007-1-4 18:35:


我要的效果就是要它没有定义过,要是定义过了,那不就重复了嘛!

  实际上,if not defined !_num%a%! 这一句始终为真,也就是说,这一部分语句有和没有的效果是一样的,并不能控制那个变量是否已经被定义过,你添加跳转语句来循环执行,多次执行之后,就会看到有重复的数值出现了。可能你还不太明白我为什么说那一句始终为真,索性再多说几句吧:你在上一句用了 set /a _num!a!=%random:~-2% 来定义变量 _num!a!,下一句你用 if not defined !_num%a%! 来判断的是 变量_num!a! 的值(而非变量本身) 是否被定义。

   另外,你的代码并没有处理 08 和 09 ,会出错的。

[ Last edited by namejm on 2007-1-4 at 07:16 PM ]
作者: balinger     时间: 2007-1-5 08:02
复杂的事交给电脑去做。我来个简单的。
@echo off
:loop
set s1=%RANDOM:~-2%
set s2=%RANDOM:~-2%
set s3=%RANDOM:~-2%
set s4=%RANDOM:~-2%
set s5=%RANDOM:~-2%
set /a h=s1*s2*s3*s4*s5*(s1-s2)*(s1-s3)*(s1-s4)*(s1-s5)*(s2-s3)*(s2-s4)*(s2-s5)*(s3-s4)*(s3-s5)*(s4-s5)
if h equ 0 goto :loop
echo %s1%  %s2%  %s3%  %s4%  %s5%
pause
goto :loop
作者: tao0610     时间: 2007-1-5 08:02
13楼的代码可以简化一下.
@ECHO OFF
setlocal ENABLEDELAYEDEXPANSION
SET T=1

:PR
FOR /L %%A IN (%T%,1,100) DO (
SET/a NO%%A=!random!%%100+1
SET /A H=%%A-1
FOR /L %%B IN (!H!,-1,1) DO (
IF !NO%%A!==!NO%%B! (SET T=%%A&GOTO PR))
echo !NO%%A!>>222.txt)
pause
批处理对CALL和FOR的嵌套执行效率并不高,能不用最好不用.
@echo off&setlocal enabledelayedexpansion
set t=1
:PR
for /l %%a in (%t% 1 100) do (
set/a a%%a=!random!%%100+1
if not defined !a%%a! (echo !a%%a!>>123.txt) else set t=%%a&goto PR
set !a%%a!=flag
)
pause

作者: namejm     时间: 2007-1-5 08:08
  22楼通过几个数字相减是否为0来判断数字是否重复,确实是个思路,只是仍然没有处理好把字符串数值化的细节,导致截取到形如 02、03 的字符串(而非数值)。
作者: youxi01     时间: 2007-1-5 08:21


  Quote:
Originally posted by namejm at 2007-1-5 07:57 AM:

  实际上,if not defined !_num%a%! 这一句始终为真,也就是说,这一部分语句有和没有的效果是一样的,并不能控制那个变量是否已经被定义过,你淠...

明白了,还真的是笨,哈哈,不好意思!
作者: balinger     时间: 2007-1-5 09:12


  Quote:
Originally posted by namejm at 2007-1-5 08:08 AM:
  22楼通过几个数字相减是否为0来判断数字是否重复,确实是个思路,只是仍然没有处理好把字符串数值化的细节,导致截取到形如 02、03 的字符串 ...

多谢指教,修改如下:
@echo off
:loop
set s1=%RANDOM:~-2%
set /a s1=s1*1
set s2=%RANDOM:~-2%
set /a s2=s2*1
set s3=%RANDOM:~-2%
set /a s3=s3*1
set s4=%RANDOM:~-2%
set /a s4=s4*1
set s5=%RANDOM:~-2%
set /a s5=s5*1
set /a h=s1*s2*s3*s4*s5*(s1-s2)*(s1-s3)*(s1-s4)*(s1-s5)*(s2-s3)*(s2-s4)*(s2-s5)*(s3-s4)*(s3-s5)*(s4-s5)
if %h% EQU 0 goto :loop
echo %s1%  %s2%  %s3%  %s4%  %s5%
pause
goto :loop
作者: 26933062     时间: 2007-1-5 09:51
请问斑主,你6楼的代码中红字部分是什么意识?
@echo off
set count=0

:loop
set /a num=%random%%%99+1
if not defined num%num% (
    set num%num%=%num%
    set /a count+=1
    call echo %%num%%
)
if %count% lss 5 goto loop

pause>nul
作者: namejm     时间: 2007-1-5 10:04
  楼主你终于来了啊,可把大家想坏了。盼星星盼月亮,终于把你盼到了,总算在顶楼把意思表达清楚了,看来大家的猜测还不算离谱,呵呵。

  玩笑过后,言归正传。defined 的词义是定义的意思,在批处理中,用 if defined 变量名 这样的语句来检测某个变量是否已经被定义过(也就是有没有被赋值)。既然你要在1-100(包括1和100)这个范围内显示随机数,把我那个代码里的99改为100就可以了。
作者: 26933062     时间: 2007-1-5 10:12
谢谢版主的解答,不过你好像又在21楼推翻了自己的方法,(21楼的解释我没看的太懂)那么你6楼的方法到底行不行呢?我试过好几次了,好像还行.
作者: namejm     时间: 2007-1-5 10:27
  4楼的思路是正确的,我在21楼只是指出了4楼代码的错误之处而已,而6楼的代码修正了那些错误,并没有推翻我的方法。

  另外,我在16楼描述了一个奇怪的现象,可能是call语句的特殊之处,也可能是CMD的一个bug,我现在都还没搞明白是怎么回事,希望能引起你的重视。

——————————————————————————————————————
  原因已经找到,请看41楼的分析,然后再使用42楼的代码。

[ Last edited by namejm on 2007-1-6 at 05:08 PM ]
作者: 26933062     时间: 2007-1-5 11:10
谢谢各位!辛苦了!!!
作者: qzwqzw     时间: 2007-1-5 12:15
实际上这是一个生成P(m,n)随机数列的问题

当m远大于n时可以采用楼上各位的碰撞式生成

但当n接近m时,碰撞生成效率极低

此时通常采用顺序数列随机排序或者顺序数列随机选取方法

下面是一个P(100,100)的例子,即生成100个互不重复的0~99之间的随机数列
:: 生成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
)

:: 对数列进行随机交换
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!
)

set rnum
pause

作者: zh159     时间: 2007-1-5 12:27

@echo off
:start
cls
set Num=
set Tmp$=

:loop
set /a randomloop=%random%%%99+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 5 goto loop

for /l %%n in (1,1,%Num%) do call set /p= %%random_%%n%%<nul
echo.
pause
goto start
exit
可以“echo %Tmp$%”显示,也可以“set random_”显示
作者: lxmxn     时间: 2007-1-6 01:47

  经过多次测试,发现13楼的代码很怪,结果中的五个数中的第一个数很容易和下一次测试结果中的第一个数相同,不知道是什么原因,可能代码有问题。

  下面是我连续测试五遍的结果:
附件 1: 1111.BMP (2007-1-6 01:47, 233.04 K, 下载附件所需积分 1点 ,下载次数: 6)



作者: tghksj     时间: 2007-1-6 03:42
又是 qzwqzw 我的偶像啊~~

32楼看不懂啊~~~~~我受不了了~你的每个代码我都得看上一两天...

求求你逐句解释一下行吗???妈妈密啊~~~受不了了~~!!!

----------------------------------

34楼你运气好,我这没出现这这样的情况.今天买张彩票试试!!一定中!!!!!:)

[ Last edited by tghksj on 2007-1-5 at 03:01 PM ]
作者: lxmxn     时间: 2007-1-6 04:29


  Quote:
Originally posted by tghksj at 2007-1-5 14:42:
又是 qzwqzw 我的偶像啊~~

32楼看不懂啊~~~~~我受不了了~你的每个代码我都得看上一两天...

求求你逐句解释一下行吗???妈妈密啊~~~受不了了~~!!!

--- ...


  晕,这跟运气有什么关系?我今天测试了N遍都是这样的情况。

作者: zh159     时间: 2007-1-6 09:01


  Quote:
Originally posted by lxmxn at 2007-1-5 12:47:

  经过多次测试,发现13楼的代码很怪,结果中的五个数中的第一个数很容易和下一次测试结果中的第一个数相同,不知道是什么原因,可能代码有问题。

我连试了十多次,间隔几分钟后再试也一样
作者: namejm     时间: 2007-1-6 10:32
  要显示1-100这个范围的随机数是极其简单的事情,问题的关键是要排除掉重复的数字,这样就增加了一些工作量。
作者: 26933062     时间: 2007-1-6 10:50
是啊,版主,你6楼的代码,经过多次测试,同样发现了重复的现象.
作者: balinger     时间: 2007-1-6 12:01
个人认为32 楼是唯一正解。先建立符合要求的的所有数码的顺序数列,再对顺序数列随机排列。随意取任意位,一定会同时满足不重复、随机的要求。其它思路,先取若干符合要求随机数码,再判断是否重复,理论上都有死循环的可能。
作者: namejm     时间: 2007-1-6 12:46


  Quote:
Originally posted by 26933062 at 2007-1-5 21:50:
是啊,版主,你6楼的代码,经过多次测试,同样发现了重复的现象.

   不会吧?我已经通过 if not defined 语句来控制变量是否重复来排除重复的值了,从理论上来说是不可能有重复的值出现的,并且,经过我不小于100次的测试,始终没有发现重复值,请问你是如何多次重复测试的?

  另外,在回这个帖子的过程中,突然明白了我在16楼所描述的奇怪现象是怎么造成的:原来,当num%num%从num1到num99这99个变量都被定义之后,第20次的第5个值应该是第100个值了,此时,可被利用的变量名都已经被定义过了,所以,程序只能在 loop 和 goto loop 之间打转转,造成了死循环。应当在适当的地方把所有的变量清空就可以解决16楼所说的奇怪问题了。
作者: namejm     时间: 2007-1-6 13:07
  对6楼的代码稍作修改,使得代码可以重复N次而不会出现16楼所说的现象:
@echo off
:begin
cls
set times=0
set count=0

:loop
set /a num=%random%%%99+1
if not defined num%num% (
    set num%num%=%num%
    set /a count+=1
    call echo %%num%%
)
set /a times+=1
if %times% equ 20 (
    for /l %%i in (1,1,99) do set num%%i=
    set times=0
)
if %count% lss 5 goto loop
pause>nul
goto begin

作者: dikex     时间: 2007-1-6 14:02
凑凑热闹也发一个

  Quote:
@echo off
set count=1
set num=
echo %random% >nul
:DORND
set /a rnd=%random%*100/32767+1
echo %num% | find " %rnd% " && goto DORND
set num=%num% %rnd%
set /a count+=1
if %count% lss 6 goto DORND
echo %num%
pause

各位看到第四行可能会觉得奇怪,关于这个请看下面xmxn的提问和我的个人见解

  Quote:
Originally posted by lxmxn at 2007-1-5 12:47 PM:

  经过多次测试,发现13楼的代码很怪,结果中的五个数中的第一个数很容易和下一次测试结果中的第一个数相同,不知道是什么原堮..

这个貌似是产生随机数的方法有问题,直接连续多次运行下面的语句

  Quote:
@echo off
set count=1
:loop
echo %random% & echo.
set /a count+=1
if %count% lss 10 goto loop
pause

这是我们会发现几次连续运行第一个出来的数字大小慢慢地增大,而之后的没有问题,时间间隔长一点第一个数的增幅就大一点,难道这个产生随机数的方法是于时间之类的有联系?随机产生的原数字大小差不多,经过某些运算后得到的结果一样也不为奇了,如果是这样的话,把第一个随机数舍弃或者使用另外一个运算就可以了
作者: lxmxn     时间: 2007-1-6 14:25


  Quote:
Originally posted by dikex at 2007-1-6 01:02:
凑凑热闹也发一个



各位看到第四行可能会觉得奇怪,关于这个请看下面xmxn的提问和我的个人见解



这个貌似是产生随机数的方法有问题 ...


  这个猜想有点问题吧??

  看下面的代码:按理说来,for命令的执行速度是非常快的,但是下面代码所产生的随机数大小变化却是比较大的,是不是就排除了“随机数的产生和时间有关”这一说?
@echo off&setlocal enabledelayedexpansion
for /l %%a in (1,1,20) do echo !random!
pause

作者: dikex     时间: 2007-1-6 14:41
嗯,有道理……
又一个猜想出现了^_^
可能时间只是产生时的其中一个参数,还与上一个随机数有关,而上一个经过某些放大差别以及和时间相关的运算后,第二个就是名副其实的随机了
总之%random%产生随机数的方法有点问题,各位使用时注意一下,必要时舍弃第一个随机数

P.S.听过某人说vb产生随机数也是很特殊的,不知和这个是否差不多,猜想……猜想……继续猜想……
作者: zh159     时间: 2007-1-6 15:28
用“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

作者: 9527     时间: 2007-1-6 23:47
这几天看你们讨论这个帖子这么热闹,自己也忍不住试一把,以下代码测试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!

作者: lxmxn     时间: 2007-1-7 01:18

  9527 的代码测试通过,效果也不错,每次的数都很“随机”,加分。

作者: lxmxn     时间: 2007-1-7 01:19


  Quote:
Originally posted by dikex at 2007-1-6 01:41:
嗯,有道理……
又一个猜想出现了^_^
可能时间只是产生时的其中一个参数,还与上一个随机数有关,而上一个经过某些放大差别以及和时间相关的迠...


  兄的发散思维令人佩服。

作者: namejm     时间: 2007-1-7 01:26
  那我也再帖一段代码,不用 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 ]
作者: tghksj     时间: 2007-1-7 02:14
13楼产生重复的原因主要出在是取%random%的前两位.

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

就不成问题了.

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

13楼的代码与其相比简直就是一个笑话....
作者: namejm     时间: 2007-1-7 02:33


  Quote:
Originally posted by tghksj at 2007-1-6 13:14:
其实对于这个问题已经没有什么好继续讨论的了,32楼的代码已经完全解释并解决了.

  同一问题,可以换用不同的思路来解决,最终是殊途同归,但精彩部分在于解决问题的过程而不是最终结果;或者根本得不到完美的结果,但是解决问题的过程却能给他人以启发。只要还有不同的解法,继续讨论下去还是有好处的。
作者: tghksj     时间: 2007-1-7 04:55
对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 ]
作者: namejm     时间: 2007-1-7 05:47
  实际上,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中的任一变量来置换,从而保证了数值的不重复性。整体的思路就是先顺后乱,以达到随机的目的。
作者: zh159     时间: 2007-1-19 13:43
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 ]
作者: everest79     时间: 2007-1-19 22:27

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

作者: stornager     时间: 2007-4-3 05:43
set random1=%random:~-2%
代码中%random:~-2%这个变两‘量有何含义?????????
作者: flyinspace     时间: 2007-4-3 07:41
同时显示5个数字哦。

还是5位数??