function TestBit(Value, Index : integer) : Boolean; asm BT EAX, EDX SBB EAX, EAX AND EAX, 1 end;procedure TForm1.Button1Click(Sender: TObject); const A : array[0..4] of Char = ('A','B','C','D','E'); var I, J: Integer; Temp: string; begin for I := 1 to 31 do begin Temp := ''; for J := Low(A) to High(A) do if TestBit(I, J) then Temp := Temp + A[J]; Memo1.Lines.Add(Temp); end; end; 测试结果:A B AB C AC BC ABC D AD BD ABD CD ACD BCD ABCD E AE BE ABE CE ACE BCE ABCE DE ADE BDE ABDE CDE ACDE BCDE ABCDE
说一下一楼算法的思路,以免楼主看不懂(这个算法不是递归算法):首先,把数组每一个元素用一个二进位表示,例如:A B C D E 1 1 1 1 1 ---> 于是它最多有11111(二进制)种不重复组合(即31种)(不考虑顺序--按楼主要求)于是,只要检查从1到31这些数字的二进位哪些是二进制值1,就可以得出组合了。(位值为1的元素选取,位值为0的元素弃之)函数TestBit是我以前写的一个小函数,用于检查某整型数某二进位值,如果该位为1返回True。这个函数从来没有用到过,用在这里了。^_^
1楼方法挺不错的,极限是长度32的数组,用 if Boolean((I shr J)and 1) then 更好懂一些
lihuasoft 的方法很好很强大!
一个回溯算法的例子:procedure TForm1.Calc(M : array of Integer); var N : Integer; A : array of Integer; i , p: Integer; X : Integer; S : String; begin N := Length(M); SetLength(A, N); for X := 0 to N - 1 do begin for i := 0 to N - 1 do A[i] := -1; p := 0; while p >= 0 do begin if A[p] = -1 then begin if p = 0 then A[p] := 0 else A[p] := A[p - 1] + 1; end else inc(A[p]); if A[p] >= N then begin A[p] := -1; dec(p); end else begin inc (p); if p > X then begin S := ''; for i := 0 to X do begin if s <> '' then s := S + ','; S := S + IntToStr(M[A[i]]); end; memo1.Lines.Add(S); dec(p); end; end; end; end; end;procedure TForm1.Button1Click(Sender: TObject); const M : array [0..3] of Integer = (1, 2, 3, 4); begin Calc(M); end;
function TestBit(Value, Index : integer) : Boolean;
asm
BT EAX, EDX
SBB EAX, EAX
AND EAX, 1
end;procedure TForm1.Button1Click(Sender: TObject);
const
A : array[0..4] of Char = ('A','B','C','D','E');
var
I, J: Integer;
Temp: string;
begin
for I := 1 to 31 do begin
Temp := '';
for J := Low(A) to High(A) do
if TestBit(I, J) then Temp := Temp + A[J];
Memo1.Lines.Add(Temp);
end;
end;
测试结果:A
B
AB
C
AC
BC
ABC
D
AD
BD
ABD
CD
ACD
BCD
ABCD
E
AE
BE
ABE
CE
ACE
BCE
ABCE
DE
ADE
BDE
ABDE
CDE
ACDE
BCDE
ABCDE
说一下一楼算法的思路,以免楼主看不懂(这个算法不是递归算法):首先,把数组每一个元素用一个二进位表示,例如:A B C D E
1 1 1 1 1 ---> 于是它最多有11111(二进制)种不重复组合(即31种)(不考虑顺序--按楼主要求)于是,只要检查从1到31这些数字的二进位哪些是二进制值1,就可以得出组合了。(位值为1的元素选取,位值为0的元素弃之)函数TestBit是我以前写的一个小函数,用于检查某整型数某二进位值,如果该位为1返回True。这个函数从来没有用到过,用在这里了。^_^
var
N : Integer;
A : array of Integer;
i , p: Integer;
X : Integer;
S : String;
begin
N := Length(M);
SetLength(A, N);
for X := 0 to N - 1 do
begin
for i := 0 to N - 1 do A[i] := -1;
p := 0;
while p >= 0 do
begin
if A[p] = -1 then
begin
if p = 0 then
A[p] := 0
else
A[p] := A[p - 1] + 1;
end
else
inc(A[p]);
if A[p] >= N then
begin
A[p] := -1;
dec(p);
end
else begin
inc (p);
if p > X then
begin
S := '';
for i := 0 to X do
begin
if s <> '' then s := S + ',';
S := S + IntToStr(M[A[i]]);
end;
memo1.Lines.Add(S);
dec(p);
end;
end;
end;
end;
end;procedure TForm1.Button1Click(Sender: TObject);
const
M : array [0..3] of Integer = (1, 2, 3, 4);
begin
Calc(M);
end;