枚举组合类型 ( 积分: 100 )

  • 主题发起人 主题发起人 squarevictory
  • 开始时间 开始时间
S

squarevictory

Unregistered / Unconfirmed
GUEST, unregistred user!
说明:
N是分组个数 取值范围:N<=5;
M={0,1,2,3,4,5,6,7,8,9} 同一组内得M不能重复,不同组内可以有不相同的M
例:
N=3
N1:M1,M2
N2:M6,M2,M7
N3:M5
组合结果:
M1M6M5,M1M2M5,M1M7M5,M2M6M5,M2M2M5,M2M7M5
例:N=3
3,6;
5,7,9;
2
组合结果:
352,372,392,652,672,692
例:N=2
3,6;
5,7,
组合结果:
35,37,65,67

根据N的取值来求出所有组合
 
例:
N=3
N1:M1,M2
N2:M6,M2,M7
N3:M5
Result
Count := 0;
for i := 0 to N1Count - 1do
for j := 0 to N2Count - 1do
for k := 0 to N3Count - 1do
begin
Result[Count] := Format('%S%S%S', N1, N2[j], N3[k]);
Inc(Count);
end;
 
m,n均可建为字符数组,然后嵌套N个循环来遍历各数组组合
 
MUHX兄:
N值是不确定的,因此不能预先知道有多少个圈套的循环。
 
用穷举法列举就可以了,就像上面的代码
不过最好在这前判断一下一组内有没有重复数据
 
可以具体点吗?给出关键代码即可,其实原理大概知道。
 
如果不知道N的值的话,就用递归吧
 
具体代码我也没想好,但我知道这类问题用递归比较容易解决,而用循环就麻烦了
 
可以参与inttostr函数用递归的实现方案,网上应当有,你查一查
 
好的 我先向递归这方向想想
 
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);
procedure FormCreate(Sender: TObject);
private
Grps: array of TStringList;
{ Private declarations }
public
N: Integer;
{ Public declarations }
procedure Showtype(List: TStringList;
Level: Integer;
output: string);
end;

var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
I,J,K: Integer;
Old, Tmp: TStringList;
begin
Old := TStringList.Create;
Tmp := TStringList.Create;
Old.Add('T0');
//打印枚举类型就省了 用逐个加入代替之
Old.Add('T1');
Old.Add('T2');
Old.Add('T3');
Old.Add('T4');
Old.Add('T5');
Old.Add('T6');
Old.Add('T7');
Old.Add('T8');
Old.Add('T9');
Randomize;
N := Random(4) + 1;
SetLength(Grps, N);
for I := 0 to N - 1do
begin
Grps := TStringList.Create;
Tmp.Clear;
Tmp.CommaText := Old.CommaText;
for J := 1 to 2do
//这里我设置每组数据为2个 当然可以用随机数 Random(9) 取代之
begin
K := Random(Tmp.Count - 1);
Grps.Add(Tmp.Strings[K]);
Tmp.Delete(K);
end;
Memo1.Lines.Add(Grps.CommaText);
end;

Memo1.Lines.Add('分组如下');
Showtype(Grps[0], 0, '');
for I := 0 to N - 1do
begin
Grps.Free;
end;
Tmp.Free;
Old.Free;
end;

procedure TForm1.Showtype(List: TStringList;
Level: Integer;
output: string);
var
I: Integer;
T: string;
begin
for I := 0 to List.Count - 1do
begin
if Level < N - 1 then
begin
Showtype(Grps[Level + 1], Level + 1, output + List + ',');
end else
begin
T := output;
T := T + List;
Memo1.Lines.Add(T);
end;
end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
Memo1.Clear;
end;

end.
 
每组数据不固定

L := Random(9);
for J := 0 to Ldo

begin
K := Random(Tmp.Count - 1);
Grps.Add(Tmp.Strings[K]);
Tmp.Delete(K);
end;
取代
for J := 1 to 2do

begin
K := Random(Tmp.Count - 1);
Grps.Add(Tmp.Strings[K]);
Tmp.Delete(K);
end;
 
除了求出组合外,因为不同组内可以有相同的M,因此会有相同的组合出现,最后结果还要剔除相同的组合。
 
把Tmp.CommaText := Old.CommaText;
拿到循环外边 就可以做到完全不重复
0 0
3 4
4 3
034 033 043 044
不知道楼主的本意是不要认为034 043输入重复需要删除之??
 
to nicai_wgl
不同组内可以有相同的M
这个楼主似乎没有提到哦 楼主的用例也看不出有不同组同值的情况
不过这个问题的确值得在考虑[:D]
 
气氛越来越热烈了 ,THANKS ALL。
中午午休一下,下午进行调试
 
不好意思 ,改下
原版: M={0,1,2,3,4,5,6,7,8,9} 同一组内得M不能重复,不同组内可以有“不”相同的M
正确: M={0,1,2,3,4,5,6,7,8,9} 同一组内得M不能重复,不同组内可以有相同的M
例如
0 0
3 4
4 3
第二行内不能再有3或4了,但第三行可以有3或4
另外
034 033 043 044
034,043是不同的组合。
 
那我那个应该能满足楼主的需要
王婆卖瓜一把[:D][^]
 
AVALON兄:
谢谢,功能比较合我意。不过我还要将代码转换成C#,途中可能会出点小问题,再请教。
明天下班前结帖。
 
C#我只是随便看过 对里面的数据类型不熟悉
只要有类似TList的链表数据类型 转换非常easy啦[:D]
 
后退
顶部