高分求购组合算法(200分)

  • 主题发起人 主题发起人 tpeisc
  • 开始时间 开始时间
T

tpeisc

Unregistered / Unconfirmed
GUEST, unregistred user!
15选5(C 15 5)的所有组合为3003个,那位高手能写一个算法得到全部的组合?
急用!!!!!
 
想了一个早上只得了一个思路,还没写代码.
 
type
TT = Record
Value : Array [0..4] of Integer ;
end;
Data : Array of TT;
Source,tmpArray : array of integer ;
procedure GetValue(Dest:Array of Integer;Loc,FillLoc,BegLoc,EndLoc:integer);
var
i,j : integer ;
begin
for i := BegLoc to EndLocdo
begin
if High(Dest) = Loc then
//到了最后一位,表示得到一个组合数了
begin
for j := 0 to Loc -1do
begin
Data[FillLoc].Value[j] := Dest[j] ;
end;
Data[FillLoc].Value[Loc] := Source;
FillLoc := FillLoc + 1 ;
end
else
begin
Dest[Loc] := Source ;
Loc := Loc + 1 ;
GetValue(Dest,Loc,FillLoc,i+1,EndLoc+1);//
end;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
i : integer ;
begin
setLength(Source,15);
setLength(tmpArray,5);
SetLength(Data,3003);//3003 可以计算得到的 15*14*13*12*11 div 5*4*3*2*1
for i:= 0 to 14do
Source := i+1 ;
GetValue(tmpArray,0,0,0,10);
end;
我的算法是从这里得到的,对于其他的例如N选M(M<=N),你自己可以从算法里变通下,
var A1,A2,A3,A4,A5 : integer ;//所有组合数的任一个为 A1,A2,A3,A4,A5
for A1 := 0 to 10do
for A2 := A1+1 to 10+1do
for A3 := A2+1 to 10+1+1do
for A4 := A3+1 to 10+1+1+1do
for A5 := A4+1 to 10+1+1+1+1do

begin
Data[0] := A1 ;
Data[1] ;= A2 ;
...
end
 
使用递归算法,最简单
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
implementation
type
TElements = array[1..15] of Integer;
TSelected = array[1..5] of Integer;
TOutputCallBack = procedure (const ret: TSelected);
function GetSel(const Elements: TElements;
Start: Integer;
var Selected: TSelected;
SelCount: Integer;
var RetS: String): Boolean;
var
i, j: Integer;
t: String;
begin
Result := False;
if Start > 15 then
Exit;
if SelCount > 5 then
Exit;
SelCount := SelCount + 1;
for i := Start to 15do
begin
Selected[SelCount] := Elements;
if SelCount = 5 then
begin
for j := 1 to 5do
begin
if j = 1 then
t := IntToStr(Selected[j])
else
t := t + ',' + IntToStr(Selected[j]);
end;
if RetS = '' then
RetS := t
else
RetS := RetS + #13#10 + t;
end;
GetSel(Elements, i + 1, Selected, SelCount, RetS);
end;
end;

{$R *.dfm}
var
m: TElements = (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15);
n: TSelected;
procedure TForm1.Button1Click(Sender: TObject);
var
ms: String;
begin
GetSel(m, 1, n, 0, ms);
Memo1.Lines.Text := ms;
Caption := IntToStr(Memo1.Lines.Count);
end;

end.
 
还在研究中,越想越有意思
 
还是使用排列组合较好一些吧!
 
这个问题很简单,只要定义一个数组 A[0..4] array of integer,再用一个递归函数就行了。
我把代码发到你邮箱里了,你自己看吧。
有感性趣的朋友发信向你要吧。
 
非常感谢大家的帮助。你们代码我还没试过,写者有分,哈,,,,,
to JebelStream 代码早上就收到了,上机一试,还行!通过了。那个办法比较对我的心思。只是有些死板,反正我也只是用于15选5。哈,,,,,我想用它来做彩票分析用。过两天把程序发给你看看。
有要那段代码的朋友给我写信吧。tpeisc@yahoo.com.cn
 
呕血,我还在想怎么提高它的性能呢.
 
后退
顶部