模拟彩票 M个数里头取N个数,征算法。 (50分)

N

Nizvoo

Unregistered / Unconfirmed
GUEST, unregistred user!
列出所有的数据组合~
共有15120种
只是取数时的算法不好确定。
至少要取15120啊~~~
如果取
[blue]不要如下所写[/blue]
代码:
var
  I, J, K, M, N: Integer;
  BeTime: Real;

begin
  BeTime := GetTickCount;

  for I := 1 to 9 do
    for J := 1 to 9 do
      for K := 1 to 9 do
        for M := 1 to 9 do
          for N := 1 to 9 do
            if (I <> J) and (I <> K) and (I <> M) and (I <> N) and
              (J <> K) and (J <> M) and (J <> N) and
              (K <> M) and (K <> N) and
              (M <> N) then
              frmChoose.mmoResult.Lines.Add(Format('%d %d %d %d %d',
                [I, J, K, M, N]));

  BeTime := GetTickCount - BeTime;
  BeTime := (Round((BeTime / 1000) * 100)) / 100;

  frmChoose.lblCount.Caption := Format('总数目:%d 条 用时: %s秒',
    [frmChoose.mmoResult.Lines.Count, CurrToStr(BeTime)]);
 
咋个没应声呢????
 
是组合的吗?组合的算法可不是这样。
组合的需要看什么情况了,我以前做个一个计算的,不过知识计算特等奖、一等奖。
其它得太麻烦。
 
把M应该置入数组进行取

 
我作过一段程序,利用递归实现,非常简单
----------------------------
要从n(假设这n个数为1到n)个数中取出m个数,我们可以先确定是否有第一个数,如果有1,那么从余下的n-1个数中取出m-1个就可以了;而要是没有1,则需要从余下的n-1个数中选出m个数。这样,我们就把问题进行了降级处理,那么什么时候递归结束呢?如果要从若干个数中取出0个,那么说明不需要再进行选取了,认为递归结束;另外一种情况是,要从p个数中选出p个数,这时确定的选法就是这p个数,所以也可以把这p个数作为结果,然后结束递归。这样,我们就确定了组合问题的降级处理和结束条件。
我们用过程select来实现组合选数。参数setvailable代表可供选择数的集合,m表示需要从集合setvailable中选取m个元素,setselected表示已经选出来的元素。
具体实现如下:
procedure select(setavailable:set of 1..n,m:integer;setselected:set of 1..n);
begin
if m=0 then exit
//不需要选择,结束递归
if CountOfElement(setavailable)=m then
//从m个数中选出m个,那么把setavailable和setselected的并集作为结果,结束递归
begin
puttoresult(setavailable+setselected);
exit
end;
//到此,如果没有结束,则需要对问题进行降级
select(setavailable-[FirstElement(setavailable)],m-1,setselected+[ FirstElement(setavailable)]);
//选中集合中的第一个元素,然后从余下的元素中选取m-1个元素
select(setavailable-[FirstElement(setavailable)],m,setselected);
//若不选择第一个元素,则从余下的元素中选取m个元素
end;
在上面的程序中,FirstElement从一个集合中取出最小的元素,CountOfElement计算一个集合中的元素个数,puttoresult把得到的组合记录下来,这些函数和过程的实现略去。
 
楼上兄,谢谢你的代码
我不想用递归的。
我想做15120次循球,我取这么多次。
我只是想取数。

 
祝你中奖,可惜那些彩票都是用乒乓球来搞的,没得规律。
 
我是学习啊,不是去中奖,我是为了形象一点。才出此下策
 
咋个无人哪???

help me???
 
为什么不想用递归?
你到底是要求什么?

列出所有的组合?


 
对,我就是要列出所有的组合,但我知道总数。
我就是要取数。我不会取
 
类似于洗牌的方法:从54张牌中随机抽取N(N<54)张不重复的牌。
对于彩票则可视为:从1-35中随机抽取7个不重复的数。

{类Java语言描述}
// 彩票基号
int[] WelfareLotteryNo = [1..35];

public Object GetLotteryValue() {
// 存放彩票号
Vector lotteryV = new Vector();
// 首先将彩票基号重排
int LotteryValue = 0;
for (int i = 0
i < 7
i++) {
int tmp = (int)( Math.random() * (29 - i) );
LotteryValue = WelfareLotteryNo[tmp];
WelfareLotteryNo[tmp] = WelfareLotteryNo[29 - i];
WelfareLotteryNo[29 - i] = LotteryValue;
}
// 察看重排后的彩票基号
for (int i = 0
i < 30
i++) {
System.out.print(WelfareLotteryNo + ",");
}
// 取得彩票号
for (int i = 0
i < 7
i++) {
lotteryV.add(new Integer(WelfareLotteryNo[29 - i]));
}
return lotteryV;
}

 
可否用集合的概念来做?

你的这所有可能的号码构成一个全集,当需要取彩票号的时候,用随机整数来确定它在集合中
的位置,对于要保证每个号码仅生成一个,另外用标志来标志是否已经产生过了,没产生用
0表示,产生过了用1表示,为了减少标志所占用的空间,可以用一些整数的位来表示,这样
进行判断的时候用位运算就可以了,而且速度也不慢吧?

期待更好的想法?
 
多人接受答案了。
 
顶部