急救(面试题)(100分)

  • 主题发起人 主题发起人 94132195
  • 开始时间 开始时间
9

94132195

Unregistered / Unconfirmed
GUEST, unregistred user!
我现正在见工,这个老板娘叫我做一题目,我做了半天都没头绪,请各位兄弟姐妹快快帮忙
救命之恩吾将永生难忘
题目如下:
假设有一个全局数组 A:Array[0..99] of integer,
请用delphi设计一个子程序,要求每次调用,在数组中产生一个0..99的随机排列,并简要
说明算法,万望各位各抒已见
 
Randomize;//初始化随机数
var
i: Integer;
begin
Randomize;
for i := 0 to 99do
begin
{ Write to window at random locations }
A:=Random(100)
end;
end;
 
要求每次把100个数据重新排序后调出
 
procedure GetArray();
var
iRec,iLoop,iTmp:Byte;
OkFlag: Boolean;
begin
Randomize;
for iLoop:= Low(A) to High(A)do
A[iLoop]:= -1;// 初始化
for iRec:= Low(A) to High(A)do
begin
Repeat
iTmp:= Ramdom(100);
OkFlag:= false;
for iLoop:= Low(A) to High(A)do
begin
if A[iLoop]=-1 then
Break;
if iTmp= A[iLoop] then
begin
OkFlag:= True;
Break;
end;
end;
until not OkFlag;
A[iRec]:=iTmp;
end;
end;
直接寫的,沒調試,你試試.
 
不好意思,可以有重複嗎?如果可以有,那就不必這樣複雜了,KOKS的可以.
 
帮人帮到底给我说明一下你的这个算法吧
low(a),high(a),a[iloop]是什么意思?
 
简单。初始化数组data:array [0..99] of integer;存放0。。99,每次随机产生一
个数,然后去掉这个数,直到没有。eg:
var
data:array [0..99] of integer;
i,j,k,total:integer;
resultdata:array [0..99] of integer;
begin
for i:=0 to 99do
//初始化数组data
data:=i;
total:=100;
//个数
randomize;
for i:=0 to 98do
begin
j:=random(total);
//随机产生一个数
resultdata:=data[j];

total:=total-1;
//还剩的个数
for k:=j to total-1do
//去掉选过的数
data[k]:=data[k+1];
end;
resultdata[99]:=data[0];
end;
//resultdata即随机得到的0。。99;把data换成a就成了。
 
low(A)和High(A)分別是數組A的下標的下,上限,在此題中相當於0和99,A[iLoop]就是數組的第幾個呀!
其實還有更好的算法,先從0..99初始化一次數組,然後隨機從其中取出其下標進行交換.你自己試試吧.
 
排序
for i:=0 to 98do
for j:=i+1 to 99do
if a>=a[j] then
begin
temp:=a;
a:=a[j];
a[j]:=temp;
end;
 
这是个随机问题。数字能不能重复出现?如果不能就用我的:
var i,j:integer;
flag:boolean;
begin
randomize;
i:=2;
x[0]:=random(100);
flag:=false;
repeat
x[i-1]:=random(100);
for j:=1 to i-1do
if x[i-1]=x[j-1] then
begin
flag:=true;
break;
end;
if flag then
flag:=false
else
begin
i:=i+1;
flag:=false;
end;

until i>100;
end;
调试通过
 
看一看,也没有经过调试,原理也就是这样了。
var
a,b,num:Array[0..9] of integer;//a是老板给的,b是用来存结果的,num是用来纪录已取出的序号
i,j,k,index : integer;
isFind : Boolean;//是否已取出
begin
for i := 0 to 99do
//初始化为-1
num := -1;
i := 0;
repeat
Randomise;
index:=Random(100);
isFind := false;
//下面的for语句是用来检查刚才随机取得的index谁否已经取过
for j:=0 to 99do
begin
if num[j] = -1 then
break
else
if index = num[j] then
begin
isFind := true;
break;
end;
end;
//如果没有取过,便把取得的index所对应的a[index]存入b,并进行下一个元素的取得
if not isFind then
begin
b := a[index];
for k :=0 to 99do
if num[k] <> -1 then
begin
num[k] := index;
break;
end;
i:=i+1;
end;
until i > 99//end;
 
low(a)是指数组的最小下标值
high(a)是指数组的最大下标值
 
procedure TForm1.Button1Click( Sender: TObject );
var
i, j, t: integer;
aa: array[ 0..99 ] of integer;
begin
memo1.Clear;
for i := 0 to 99do
aa[ i ] := i;
for i := 0 to 99do
begin
t := Random( 100 );
while aa[ t ] = -1do
t := Random( 100 );
a[ i ] := aa[ t ];
aa[ t ] := -1;
memo1.Lines.Add( format( 'a[%3d]=: %5d', [ i, a ] ) );
application.ProcessMessages;
end;
end;
 
验证结果如下
a[ 0]=: 0
a[ 1]=: 3
a[ 2]=: 86
a[ 3]=: 20
a[ 4]=: 27
a[ 5]=: 67
a[ 6]=: 31
a[ 7]=: 16
a[ 8]=: 37
a[ 9]=: 42
a[ 10]=: 8
a[ 11]=: 47
a[ 12]=: 7
a[ 13]=: 84
a[ 14]=: 5
a[ 15]=: 29
a[ 16]=: 91
a[ 17]=: 36
a[ 18]=: 77
a[ 19]=: 32
a[ 20]=: 69
a[ 21]=: 71
a[ 22]=: 30
a[ 23]=: 46
a[ 24]=: 24
a[ 25]=: 82
a[ 26]=: 48
a[ 27]=: 14
a[ 28]=: 87
a[ 29]=: 28
a[ 30]=: 97
a[ 31]=: 49
a[ 32]=: 88
a[ 33]=: 2
a[ 34]=: 50
a[ 35]=: 59
a[ 36]=: 65
a[ 37]=: 70
a[ 38]=: 55
a[ 39]=: 68
a[ 40]=: 95
a[ 41]=: 64
a[ 42]=: 99
a[ 43]=: 57
a[ 44]=: 33
a[ 45]=: 98
a[ 46]=: 74
a[ 47]=: 19
a[ 48]=: 78
a[ 49]=: 58
a[ 50]=: 9
a[ 51]=: 62
a[ 52]=: 54
a[ 53]=: 96
a[ 54]=: 17
a[ 55]=: 15
a[ 56]=: 26
a[ 57]=: 60
a[ 58]=: 73
a[ 59]=: 10
a[ 60]=: 79
a[ 61]=: 80
a[ 62]=: 38
a[ 63]=: 61
a[ 64]=: 43
a[ 65]=: 34
a[ 66]=: 81
a[ 67]=: 6
a[ 68]=: 22
a[ 69]=: 25
a[ 70]=: 83
a[ 71]=: 90
a[ 72]=: 76
a[ 73]=: 72
a[ 74]=: 41
a[ 75]=: 66
a[ 76]=: 11
a[ 77]=: 40
a[ 78]=: 92
a[ 79]=: 23
a[ 80]=: 94
a[ 81]=: 12
a[ 82]=: 1
a[ 83]=: 53
a[ 84]=: 44
a[ 85]=: 35
a[ 86]=: 85
a[ 87]=: 18
a[ 88]=: 89
a[ 89]=: 39
a[ 90]=: 45
a[ 91]=: 56
a[ 92]=: 75
a[ 93]=: 52
a[ 94]=: 4
a[ 95]=: 21
a[ 96]=: 51
a[ 97]=: 63
a[ 98]=: 93
a[ 99]=: 13
 
to:sky2008
你的思路不错,只是每次执行程序(指的是退出后重新运行),
得到的随机序列是相同的
建议把种子变变
 
sky2008:
在你的Memo1.clear 後加一句 ;
randomize;
試試
 
sky2008的程序OK了,只是他的数组定义的时候没有定义a数组,请你注意,别紧张
 
效率比较高的一种方案:
var
a:integer;
Temp:integer;
i,j:integer;
M:array[0..99]of Integer;
begin

randomize;
for i:=0 to 99do

M:=i;
for i:=0 to 98do
//随机99次即可——最后一个数可以用排除法确定
begin
//此算法将被选中的数放到数组头部,然后在剩下的数中进行选取
j:=random(100-i)+i;
//每循环一次范围减1
Temp:=M;
//交换M和M[j]
M:=M[j];
M[j]:=Temp;
end;

with Memo1.Linesdo
begin
Clear;
for i:=0 to 99do
Add(IntToStr(M));
end;
end;
(大家可以参考 http://www.delphibbs.com/delphibbs/dispq.asp?lid=0542886 )
由于采用了交换法,每次选取的数字不可能发生重复,避免了双重循环。而楼上同志们的
算法均无法保证不会发生重复,必须使用类似下面的随机循环来避免重复:
while aa[ t ] = -1do
t := Random( 100 );
越靠近第100个数,效率越低——最后一个数平均要调用50次Random,倒数第二个数要调用
25次...
当然,如果在效率方面没有什么要求,大家的算法应该都可以用。
 
creation-zy的方法不错。拜托你能不能去看一下我的帖子,也是关于随机的算法问题。帖子
叫做“100分继续挑战算法高手”,放在了非技术区。
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
D
回复
0
查看
795
DelphiTeacher的专栏
D
D
回复
0
查看
1K
DelphiTeacher的专栏
D
I
回复
0
查看
691
import
I
后退
顶部