组合问题(100分)

  • 主题发起人 主题发起人 andeuy
  • 开始时间 开始时间
A

andeuy

Unregistered / Unconfirmed
GUEST, unregistred user!
各位大虾:

我任意输入20个数,需要算出6个数的组合,如何写?谢谢!
 
procedure TForm1.Button1Click(Sender: TObject);
var
Value: array[1..20] of Integer;
Value2: array[1..6] of Integer;
Temp: Integer;
begin
for Temp:= 1 to 20 do
begin
Value[Temp]:= StrToInt(InputBox('','Value:',''));
end;
for Temp:= 1 to 6 do
begin
Value2[Temp]:= RandomFrom(Value);
end;

end;
 
不好意思,我的意思是所有组合数。randfrom有可能抽出相同的数,那就不是组合了! 谢谢!
 
是要总数,还是结果
 
递推是一定可以解决的
 
以下是20取3的代码,你可以将数组改为100,也可以重定义,也可以将变量m,n作为参数,注意n>=m:
procedure TForm1.SetIt();
var
a:array[1..20]of integer;
i,j,t,r,k,n,m,step:integer;
begin
n:=10;
m:=3;
t:=1;step:=0;
for j:=1 to m do begin
a[j]:=0;
while t>0 do begin
a[t]:=a[t]+1;
if a[t]>n then t:=t-1
else begin
r:=0;
for i:=1 to t-1 do
if a[t]=a then r:=100;
if r<>100 then begin
if t=m then begin
step:=step+1;
for k:=1 to t do begin
if k=1 then SL.Add('');
SL[SL.Count-1]:=SL[SL.Count-1]+' '+inttostr(a[k]);
end;
end;
if t<m then begin
//t:=t+1;a[t]:=0
{将a[t]:=0改为a[t]:=a[t-1],则为组合}
t:=t+1;a[t]:=a[t-1]

end;
end;
end;
end;
end;
end;
调用方式为:
procedure TForm1.Button1Click(Sender: TObject);
begin
if SL<>nil then FreeAndNil(SL);
SL:=TStringList.Create;
SetIt;
memo1.Text:=SL.CommaText;
end;
获得结果之后,你将相应位置的字符串替换,比如:
原来的顺序为:A,B,C,D,E,F工5个,取任意三个,那么n=5,m=3,获得SL元素结果和真实结果为:
1 2 3:A B C
1 2 4:A B D
1 2 5:A B F
1 3 4:A C D
1 3 5:A C F
1 4 5:A D F
2 3 4:B C D
2 3 5:B C F
2 4 5:B D F
3 4 5:C D E
你自己完成剩下的工作吧
 
我也写了一个,用的随机抽取法,当选组合数6或7,大于25时运行就死!dey-999朋友写的是一样会死! 还是谢谢大家!
procedure TMainFrm.GetComb();
var
i,ra: integer;
strl: TstringList;
str: String;
xxx: Boolean;
Count, Count1, Count2: Int64
//Integer;
Tot: integer;
Gstrl: TstringList;
stime,etime: word;
begin
stime:=GetTickcount;
StrL:=TstringList.Create;
StrL.Sorted:=True;
GstrL:=Tstringlist.Create;
Gstrl.Sorted:=True;


Count1:=1;
Count2:=1;
Count:=1;
For i:= 1 to J do
begin
Count1:=Count1*i;
Count2:=Count2*(n-i+1);
end;
Count:=Count2 div Count1;
Tot:=1;

Memo1.Clear;
while Tot<=Count do
begin
str:='''';
Strl.Clear;
Randomize;
for i:=0 to j-1 do
begin
xxx:=True;
ra:=RandomRange(1,n+1);

while xxx do
begin
if pos(''''+inttostr(ra)+'''',str)>0 then
ra:=RandomRange(1,n+1)
else
xxx:=False;
end;
str:=str+inttostr(ra)+'''';

StrL.Add(IntToStr(ra));
end;

str:='';
for i:=0 to j-1 do
begin
str:=str+Strl.Strings+',';
b:=StrToInt(Strl.Strings);
end;

strl.Clear;
// if not Gstrl.Find(Str,i) then
// begin
// Gstrl.Add(Str);
Str:='';
for i:=0 to j-1 do

C:=a[b-1];
BubbleSort(C);
for i:=0 to j-1 do
if i=j-1 then
str:=Str+IntTostr(C)
else
str:=Str+IntTostr(C)+',';


// Memo1.Lines.Add(Str);
// end else continue;
Tot:=Tot+1;
Label4.Caption:=inttostr(tot);
end;
Memo1.Assign(gstrl);
Label4.Caption:='运行完毕,辛苦啦!';
Strl.Free;
Gstrl.Free;
etime:=gettickcount;
Label4.Caption:=floattostr(int((etime-stime)/1000))+'秒';
end;
 
SetIt挺快,不过添加到memo1要几分钟,但是似乎不叫&quot;死&quot;吧:
procedure TForm1.SetIt();
var
a:array[1..100]of integer;
i,j,t,r,k,n,m,step:integer;
begin
n:=25;
m:=6;
t:=1;step:=0;
for j:=1 to m do begin
a[j]:=0;
while t>0 do begin
a[t]:=a[t]+1;
if a[t]>n then t:=t-1
else begin
r:=0;
for i:=1 to t-1 do
if a[t]=a then r:=100;
if r<>100 then begin
if t=m then begin
step:=step+1;
for k:=1 to t do begin
if k=1 then SL.Add('');
SL[SL.Count-1]:=SL[SL.Count-1]+' '+inttostr(a[k]);
end;
end;
if t<m then begin
//t:=t+1;a[t]:=0
{将a[t]:=0改为a[t]:=a[t-1],则为组合}
t:=t+1;a[t]:=a[t-1]

end;
end;
end;
end;
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var i:integer;
s:string;
begin
if SL<>nil then FreeAndNil(SL);
SL:=TStringList.Create;
SetIt;
s:='';
for i:=0 to SL.Count-1 do begin
if ((i+1) mod 3=0) and (s<>'') then begin
s:=s+'
'+SL;
memo1.Lines.Add(S);
s:='';
end else begin
if s='' then s:=SL
else s:=s+'
'+SL;
end;
end;
if s<>'' then
memo1.Lines.Add(S);
end;
 
算总数的话有Catalan数公式Cn=C(2n-2,n-1)/n
递归式:Cn=∑Ci*C(n-i)?(i=1..n-1,C1=C2=1)
 
dey-999,我的要求是任意整数,而不是1,2,3,4,5,6.......
tbytby,非总数。总数不要用递规啊。
 
老大,你不能加上参数SetIt(SL:TStringList);然后给数组赋值吗,或者直接将数组改为TStringList不行吗
 
dey-999,你的循环里有数组的赋值,还有内容的比较,我的要求是如:11,16,18,34,67,38,66,59,298,467......这样的任一组数的组合,你的循环可能要重写才行。把每次的组合作为真正要组合的数组的下标倒是可以! 谢谢!
 
后退
顶部