如何从30个数中随机选出7个(和允许有重复)? (100分)

  • 主题发起人 主题发起人 chateau
  • 开始时间 开始时间
C

chateau

Unregistered / Unconfirmed
GUEST, unregistred user!
如何从30个数中(1---30整数)随机选出7个(和不允许有重复)?
学习!
 

Random(30)
循环7次(Random(30))
和不允许重复?
 
var
i : integer;
begin
Randomize; { 随机数初始化 }
i:=random(30);
// 如果要取不重复的,把当前取出的数与已取的数作一下比较
.....
end;
 
用random产生随机数
for Example
var
i: Integer;
begin
Randomize;
For i := 1 to 7 do
Caption := Caption + ',' + IntToStr(random(30));//取得随机数
end;
 
var
i, k: integer;
r: array[1..7] of Integer;

function InArray: Boolean
var
j: integer;
begin
Result := False;
for j := 1 to i do
if k = r[j] then
begin
Result := True;
Break;
end;
end;

begin
for i:=1 to 7 do
begin
repeat
Randomize;
k := Random(30);
until Not InArray;
r := k;
end;
end;
 
以下代码,产生一个集合,包含7个1到30之间的随机数
var
R: set of 1..30;
I, K: Integer;
begin
Randomize;
R := [];
I := 0;
while I < 7 do
begin
K := Random(30) + 1; // Random(30) 是产生0..29的随机数
if not (K in R) then
begin
R := R + [K];
Inc(I)
end;
end;
end;
 
Randomize;
for I:=1 to 7 do
Random(30);
赋值给你需要的变量,然后使用if就可以判断是否重复
 
在数据库sql server 中可以这样写:
select top 7 [xx] from

order by newid()
这样可以做到从n个数随机选7个数,
29选7
35选7
都ok
 
1---30
应该是Random(31)吧
并且去掉取到0的结果
也可以用Random(30)+1
 
delphi中有很多关于随机数的函数
 
1,大家的思路都是顺序法,然后在所有已选数据中进行排除.
2,上面的XWHope兄说的对,我看应该用 Random(30)+1 就对了
我的思路是:(既然不允许重复,肯定需要提取列表)
1-30中任何7个数的和最大不会超过30+29+28....24
最小不会小于1+2+3+4+5+6+7
那么如下
var
i,x : integer;
iarr : array [0..6] of integer;
arrsum : integer;
begin
for i :=28 to 27*7 do
begin
while (arrsum<>i) do
begin
listbox1.items.add("此处打印取出来的数组");
arrsum :=0;
for x := 0 to 6 do
begin
iarr[x] := Random(30)+1;
arrsum := arrsum +iarr[x];
if (x<6) and (arrsum>=i) then break;
end;
if (x<6) then arrsum := 0;
end;
end;
 
楼上的算法看不懂
===============================================
1-30中任何7个数的和最大不会超过30+29+28....24
最小不会小于1+2+3+4+5+6+7
===============================================
必要条件而已, 不是充分条件
 
var
i: set of 1..30;
j: array [1..7] of Integer;
k, l: Integer;
m: string;
begin
Randomize;
k := 1;
m := '';
while k <= 7 do begin
l := Random(30) + 1;
if l in i then begin
i := i - [l];
j[k] := l;
m := m + IntToStr(j[k]) + ' ';
Inc(k);
end;
end;
Edit1.Text := m;
end;
 
to jackchin:
我说的就是必要条件.所以才能缩小范围.如果不这样,你怎么知道你所取的随机组合已经取完了????
如果结合整个代码,你可以看到这个循环中可以节省很多次判断.从而尽快取出30选7的(和不重复)的所有可能性
 
楼主的意思不是要全部取完全部的组合啊, 只要一组随机7个不重复的号码
 
搬个板凳做下来慢慢看
 
如果只是取一组,那么应该这样写:
var
i, n : integer;
Data: array [0..29] of integer;
Datacount: integer;
s: string;
begin
s := '';
for i := 0 to 29 do
Data := i;
Datacount := 30
Randomize; { 随机数初始化 }
for i := 1 to 7 do
begin
n := random(Datacount);
{ 在这里处理数据 }
s := s+inttostr(Data[n])+' ';
{ 处理完毕 }
Data[n] := Data[Datacount-1];
Datdcount := Datacount-1;
end;
end;
思路如下:
先分配一个数组,将1-30放入。
随机取一个进行处理。
将最后一个数放入刚才取的位置,数组大小减一。
这样数组里就是除了取掉的数外剩下的数了。
重复上述步骤直到取够7个数。

优点:速度快,无须比较,适用范围广,不受集合运算的限制。
缺点:如果范围比较大的话,占用内存比较多。
 
谢谢了各位!
 
多人接受答案了。
 
**** you,“和不允许重复”
怎么取一组还有这个可能吗?
看来自己都不知道自己想要什么吧?!
 
后退
顶部