怎样可以模拟上海福利彩票的1-35个不相同的数字?(100分)

  • 主题发起人 主题发起人 benbenma
  • 开始时间 开始时间
B

benbenma

Unregistered / Unconfirmed
GUEST, unregistred user!
如题,我希望可以一次模拟五个这样不相同的。
如 : 12 13 02 04 54 23 23 32
21 06 09 10 20 25 31 24
13 15 09 35 19 17 20 07
。。。。。。。。。。。。。
。。。。。。。。。。。。。
谢谢!
 
数字的出现是随机的吧?
对于每一行都是一样,先找一个小于35的数,再找第二个,如果与第一个同则不要,第三个亦然,直至找满。
其它的类推。
 
3h兄的算法效率较低,
到后来会产生很多次随机数,才能选中一个数字
我的想法是这样,
做一个长度为35的数组,将这35个书顺序存放
即a(1)=1,a(2)=2...a(35)=35
然后先产生一个1-35的随机数,取出数组中以该数为序号的那个数字
然后将该序号大于该随机数的数组元素前移一位
如第一次产生的随机数是5
则A(5)=5,
第一个数就为5
然后a(5)=a(6),a(6)=a(7)...a(34)=a(35)
然后在产生一个1。。34的随机数,
照上面步骤,直到35个数都产生
 
我也正在考虑彩票的算法。
1、号码可以重复。
2、按位分别处理(上海的有八位,四川的有七位)。
3、在统计分析数字出现机率的情况下再结合随机算法(随机函数)产生几个随机数。
这样的机率更大一些!

不知这些想法如何?希望大家都来谈谈!
 
来自:Hexi 时间:99-12-2 21:05:03 ID:163989
procedure RandomX(From,to,number:Integer;N:array of Integer);
var
Temp:Integer;
begin
if Number>(From-To) then Raise Exception.Create('无法生成。');
SetLength(N, Number);
N[0]:=-1;
for i:=1 to Number do
begin
Exist:=False;
repeat
Temp:=Random(To-From)+From;
for j:=0 to i-1 do if Temp=N[j] then
begin
Exist:=True;
Break;
end;
until not Exist;
N[i-1]:=Temp;
end;
end;


调用:
var
Num:array of Integer;
begin
Randomize;
RandomX(200,400,20,N);
.....
SetLength(N,0);
end;




--------------------------------------------------------------------------------
来自:Hexi 时间:99-12-2 21:06:17 ID:163991
更正:
var
Num:array of Integer;
begin
Randomize;
RandomX(200,400,20,Num);
.....
SetLength(Num,0);
end;




--------------------------------------------------------------------------------
来自:jiangtao 时间:99-12-2 21:08:20 ID:163993
用我的这个函数改一下,

//对0~Count的取随机array,任意两个不重复

procedure RandomIntArray(Count:Integer;PInt:PIntArray);
var
boolArray:PIntArray;
I,K,ti,tk:Integer;
begin
Randomize;

//GetMem(result,Count*sizeof(Integer));

//set array to False
GetMem(boolArray,Count*sizeof(Integer));
FillChar(boolArray^,sizeof(Integer)*Count,0);

for I := 0 to Count-1 do
begin

//randow through 0-thum-1
ti:=Random(Count-i);
tk:=0;
for k:=0 to Count-1 do
begin
if BoolArray^[k] = 0 then
Inc(tk);
if tk-1=ti then
break;
end;
BoolArray^[k]:=1;
PInt^:=k;
end;

FreeMem(BoolArray);
end;




看看我的,呵呵,正好前几天写了:procedure RandomX(From,to,number:Integer;N:array of Integer);var
iSite:array of integer
iPos:integer;begin
if Number>(From-To) then Raise Exception.Create('无法生成。');
if To < From then Raise Exception.Create('无法生成。');
SetLength(iSite, To - From + 1)
SetLength(N,Number);
for i:=From to To do iSite[i-From] := i;
for i := 1 to Number do begin iPos := random(Length(iSite));
if iPos = Length(iSite) then iPos := 0;
N[i-1] := iSite[iPos]
iSite[iPos] := iSite[High(iSite)];
SetLength(iSite,Length(iSite) - 1)
end;end;


恶贴
核心算法都有了,呵呵,
 
boat,你又来了,幸会幸会
看见那个我那个找四川老乡的题目没有?
快去捡点分数,xixi
我本想念在大家都是泸州的,多发点分给你,
以做见面礼
欢迎和我联系
wrench@263.net
 
我的考虑是,不要太过于关心算法,反正机器快的很,多几个数不多,一会儿感觉不出来。
大家不要打我 :)
 
我给个偷懒一点的:

procedure Generate;
const maxrange=35;
var i,j:integer;s:string;r:array [1..maxrange] of integer;
begin

if maxrange>254 then
exit;

s:='';

{产生ASC码为1~maxrange的字符}
for i:=1 to maxrange do
s:=s+chr(i);

randomize;
{产生随机数}
for i:=1 to maxrange do
begin
j:=random(length(s));
r:=ord(s[j]);
delete(s, j, 1);
end;

{r中就是所需要的结果}

end;
 
谢谢各位,让我开阔了思路。特别是wrench(40),cj(40),3h(30)
不过if Number>(From-To) then Raise Exception.Create('无法生成。');
这句好像。。。。
 
不愿分分是想吊胃口?:)

看iknow的:
1、什么用?
if maxrange>254 then
exit;
2、这个...效率也差不多吧,究其随机数的原理...嘿嘿...
j:=random(length(s));
 
多人接受答案了。
 
>3h:

1. 因为如果想用s这种下标引用方式来引用一个字符串中的特定
字符时, 字符串受限长度为254, 即只能是shortstring类型的

2. 不是说了是偷懒的办法嘛. ^_*
 
可是已经:
const maxrange=35;
呀!
 
当然是留作扩展功能了, 什么时候
const maxrange:integer=35;, 就可以要求用户输入个数了.
这样不用改这部分程序了呀.

一劳永懒 ^_^
 
后退
顶部