重金寻求,排列组合算法???(200分)

  • 主题发起人 主题发起人 wangxd
  • 开始时间 开始时间
W

wangxd

Unregistered / Unconfirmed
GUEST, unregistred user!
要求能够在给定的单词组中,根据给定的条件,排列组合出新的单词,最好用delphi实现
例如:
有一组单词 :a,b,c,d
算法1.要求从上面的单词组中任意选出2个单词,组成新的单词,单词不能重复,如下:
ab ac ad bc bd cd
算法2.要求从上面的单词组中任意选出2个单词,组成新的单词,单词“可以”重复,如下:
aa ab ac ad
ba bb bc bd
ca cb cc cd
da db dc dd
最后形成的结果要放到tstrings中。
注意:以上只是例子,实际的单词组不定,也有可能是a,b,c,d,e,f....
任意选出的数目也不定,有可能是任选3个单词,4个单词等等
我该怎样编写算法,能够分别形成算法1,算法2?
 
最简单的方法:四重循环
 
我已经说了,单词组及选出的单词个数不定,不能用简单的嵌套循环的
 
http://www.delphibbs.com/delphibbs/dispq.asp?lid=938125
稍稍修改一下即可
 
单词组及选出的单词个数不定,。。。
呵呵很容易死机。这样的东西,一个小小的数字就足以致死
 
“算法2”我自己解决了,用递归即可,“算法1”请大家继续啊
 
“算法1”请大家继续啊
 
这种问题用回溯最好搞定了,而且速度快。
 
用回溯方法解决:
N值为1-26表示26个字母,M为组合数
N=3,M=2时
a b
a c
b a
b c
c a
c b
=====================================

unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Memo1: TMemo;
Button1: TButton;
Edit1: TEdit;
Edit2: TEdit;
Label1: TLabel;
Label2: TLabel;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
const ch:array[1..26] of char=('a','b','c','d','e','f','g','h','i','j','k','l','m','n',
'o','p','q','r','s','t','u','v','w','x','y','z');
var a:array[0..100] of integer;
n,m,i,t,j:integer;
s:string;
begin
Memo1.Lines.Clear;
n:=StrToInt(Edit1.Text);
m:=StrToInt(Edit2.Text);//m<=n;
if m>n then ShowMessage('必须符合这个条件M<=N and N>=1!');
for i:=0 to 100 do a:=0;
t:=0;
repeat
inc(a[t]);//a[t]:=a[t]+1;
j:=0;
for i:=0 to t-1 do
begin
if a=a[t] then
begin
j:=1;
break;
end;
end;
if a[t]>n then
begin
a[t]:=0;
dec(t)
//t:=t-1;
end
else
if j=0 then
begin
if t=(m-1) then
begin
s:='';
for i:=0 to (m-1) do
begin
s:=s+format('%5s',[ch[a]]);
end;
Memo1.Lines.Add(s);
end;
inc(t);
end;
until t=-1;
end;
end.
 
调试通过了。
深度优先 和 递归 解决

procedure print_result;//输出结果
var i:integer;
begin
输出表t[1..k]即可
end;

procedure dfs(step:integer);
var i:integer;
begin
if step>k then
begin
print_result;
exit;
end;

for i:=1 to max do
begin
if (not used) then//《---如果你要求生成的单词必须是升序的,在这里加个条件and (a>a[i-1])就ok了。
begin
used:=true;
t[step]:=i;
dfs(step+1);
used:=false;//恢复状态
end;
end;
end;




{=========MAIN===========}

const max=4;k=2;//MAX是最大字母个数,K是挑选个数
var
a,t:array[1..max]of integer;//a存放原来的字母,我这里偷懒了用integer了,t表是深度优先搜索时的栈。
used:array[1..max]of boolean;//判断某个字母是否使用
I:INTEGER
//以上均为全局变量。
BEGIN
for i:=1 to max do
begin
used:=false;
a:=i;
end;
dfs(1);
END.
 
多人接受答案了。
 
后退
顶部