随机数问题:实在搞不清为什么执行这段代码后会产生相同的数字。请各位帮我改一下(100分)

  • 主题发起人 主题发起人 ldwolf
  • 开始时间 开始时间
L

ldwolf

Unregistered / Unconfirmed
GUEST, unregistred user!
此前赋NUM[1。。10]的初值全部为0,GETNUM的实参为随机产生的数字
procedure tform1.getnum(n:integer);
begin
if (n=0) or (num[n]<>0) then
begin
n:=random(10);
getnum(n);
end
else

num[n]:=n;

end;
 
randomize;了吗?
 
http://www.delphibbs.com/delphibbs/dispq.asp?lid=622076
 
递归程序
n为0到10的数字
当n<>0时,n=5时,直接执行num[5]:=5,但改变的只是num[5]的值,其余的值仍是为0
当n=0时,执行

n:=random(10);
getnum(n);

一旦n取随机数仍为0,则一直执行递归程序,直到n取随机数不为0时,例如为6,
就执行num[6]:=6,接着退出递归程序,但最终改变的只是num[6],值为6,其余
的数值不会改变,仍为0
 
先要randomize,后进行。
否则,产生的随机数将会相同。
 
TO:QuickSilver
我是用把数组赋值的方法来排除相同的数字啊?
数组 初值都为零,当改变后即NUN[N]<>0会重新取值啊。
只要N=0和NUN[N]<>任何一个条件成立都会重新取值啊,难道DELPHI中的 OR 的含义与C中的
或操作不同?
 
在每次randomize 之后再random ,
否则一定相同
 
我已RANDOMIZE;过了,难道在GETNUM里头重新取随机数的时候还要RANDOMIZE;吗?
 
Function rand(a:integer;b:integer):integer;//取随机数
begin
if b<a then result:=0 else result:=a+random(b-a+1);
end;
用它替代random(10)吧;它取不到10的
random的范围是 0 <= X < Range.
干吗一定要用递归呢?
form创建时,可以这样
Randomize;RandSeed:=rand(1,maxint);

 
Randomize;
for I := 1 to 50 do begin
{ Write to window at random locations }
Canvas.TextOut(Random(Width), Random(Height), 'Boo!');
end;
这是Delphi的代码,我测试了一下,没有问题

 
呵呵,谢谢各位了,,我不过很是想知道为什么我这段代码会出错
 
你的程序会一直产生这样的错误结果:
1:=1;2:=2;3:=3;。。。。10:=10
你可以参考下面这样做
unit Unit1;
interface
uses
Windows, SysUtils, Forms, Dialogs, StdCtrls, Classes, Controls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
public
end;

var
Form1: TForm1;
num:array[0..10] of byte;
implementation
{$R *.DFM}
Function rand(a:integer;b:integer):integer;//取随机数
begin
if b<a then result:=0 else result:=a+random(b-a+1);
end;

function asknum:byte;
var
a,b:byte;
begin
while 1>0 do begin
result:=rand(1,10);
b:=0;
for a:= 1 to 10 do if num[a]=result then b:=1;
if b=0 then break;
end;
end;

procedure clsNum;
var
a:byte;
begin
for a:= 1 to 10 do num[a]:=0;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
s:string;
a:byte;
begin
for a:=1 to 10 do num[a]:=asknum;
for a:=1 to 10 do s:=s+inttostr(a)+':='+inttostr(num[a])+#13#10;
showmessage(s);
clsNum;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
Randomize;RandSeed:=rand(1,maxint);
clsNum;
end;

end.
 
if (n=0) or (num[n]<>0) then
错误错在这句 num[n]<>0,设置数组是应该设置初始值,否则num[n]是一个随机
的值,呵呵,又到Random来了
 
改为以下就行啦。
procedure tform1.getnum(n:integer);
begin
if (n=0) or (num[n]<>0) then
begin
[red]randomize;[/red]
n:=random(10);
getnum(n);
end
else

num[n]:=n;

end;
 
TO :creation-zy 呵呵,
Num[n]:=n; 的目的就是我下面思路的第三步,麻烦看一下
代码在上面,各位参看我的思路看看。
我的思路是这样的,左看右看还是看不出毛病啊:(
1。定义数组NUM[1。。10],且初值都为0;
2。当N=0 和NUM[N]<>0(即初值已被改动)任意一个值为TRUE时,重取随机数,
3。若两个值都为FALSE,则说明该随机数不为0,且该元素NUM[N]没有被使用过,
则将获得得随机数N赋给NUN[N],则此后再取随机数时,若有相同的数,则会执行
第二步。
4。可实际操作时,还是会出现随机数相等的情况,就是说NUM[N]<>0似乎没有起到作用?WHY?我只有在FORMCREATE过程中初始化数组时,和在GETNUM中给对数组进行了操作,别的地方没有对数组进行任何操作。因此数组的值应该不会受到外界因素的影响吧?

呵呵,我在这里纠缠不清,给各位添麻烦了,还请各位原谅:)

另:我在GETNUM中加上了RANDOMIZE;重复值出现次数减少了,但是还是有重复,我想主要问题还是在第三步吧?
 
你的过程的流程是:

如果 (n=0) or (num[n]已经被赋值) 则
GetNum(一个0..9之间的随机数)
否则
Num[n]:=n; //Look Here!! 结果就是 Num[1]=1 Num[2]=2 .. Num[9]=9

调用此过程的结果是:Num数组部分元素的值为零,其他元素的值就等于他们在数组中的序号。
你想用此过程实现什么功能?是不是给Num数组中的指定的未被赋过值的元素赋以0..9的随机数?
Just use:

if (n=0) or (num[n]<>0) then
num[n]:=random(10);
 
>>还是会出现随机数相等的情况
你如何知道你的[red]过程[/red](不是函数)中到底产生了什么随机数?
一旦执行了第三步“将获得得随机数N赋给NUN[N]”,NUN[N]中的“N”就不再是原来的N了(是你新生成的随机数)。
 
都是废话,要是生成几十万或者几百万的随机数呢?
你们能肯定不重复吗?我试过肯定会重复的.就算是十几位的数一样.
而且如果你进行比较排除的话,到后来你可能会死机的.
 
多人接受答案了。
 
后退
顶部