求一算法:在m个整数中,求n个数的组合,若这n个数的和等于sum,则将这n个数打印出来。(m,n均不定,1<=n<=m,m个数的值,sum的值由界面输入.)
看起来好像很简单,实际写起来好像还有点复杂,希望各位提供算法和代码,(兼顾一下算法的效率,若m的值比较大,怎么办?总不至于在机器面前等上几十分钟吧?m的值小于100,平常一般在20左右.)不胜感激!!!!!

解决方案 »

  1.   

    所有可能的组合
    还是只要一组下面可得到一个组合
    unit Unit1;interface
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;type
      TForm1 = class(TForm)
        Button1: TButton;
        Memo1: TMemo;
        Edit1: TEdit;
        procedure FormCreate(Sender: TObject);
        procedure Sum(a: array of Integer; x: Integer);
        procedure Button1Click(Sender: TObject);
        function knap(S, n: Integer): Integer;
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;
      a: array [0..25] of Integer;
    implementation{$R *.dfm}procedure TForm1.FormCreate(Sender: TObject);
    var
      i: Integer;
    begin
      for i := 0 to 25 do
      begin
        Randomize();
        a[i] := Abs(Random(50));
      end;
    end;procedure TForm1.Sum(a: array of Integer; x: Integer);
    var
      i,j,temp: Integer;
    begin
        if ( knap(50,i) > 0 )then Memo1.Lines.Add( 'OK')
          else continue;end;procedure TForm1.Button1Click(Sender: TObject);
    var
      i,j,temp: Integer;
    begin
      for i := Low(a) to High(a) -1 do
        for j:= i+1 to High(a) do
        begin
          if a[i] > a[j] then
          begin
            temp := a[i];
            a[i] := a[j];
            a[j] := temp;
          end;
        end;
      Sum(a, 50);
    end;function TForm1.knap(S, n: Integer): Integer;
    begin
      if(S = 0) then
      begin
        result := 1;
        exit;
      end;  if ( (s< 0)or ( (s>0) and (n < 1) )) then
      begin
        result := 0;
        exit;
      end;  if (knap(s-a[n], n-1) > 0) then
      begin
        Memo1.Lines.Add(IntToStr(a[n]));
        result := 1;
        exit;
      end;
      Result := knap(s,n-1);
    end;end.
      

  2.   

    to meiqingsong(阿飛)
     所有可能的组合.谢谢你!
    to AirFish(铁甲飞鱼) ( ) 信誉:93当你有这个需求的时候,你就不会这么叫了.
      

  3.   

    to meiqingsong(阿飛)
     所有可能的组合.
     能给出所有组合的代码吗?
     万分谢你!!!
      

  4.   

    http://community.csdn.net/Expert/topic/3331/3331804.xml?temp=.964657
      

  5.   

    只能适应20左右unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls,DateUtils;const MAXLEN=26;type
      TForm1 = class(TForm)
        Button1: TButton;
        Memo1: TMemo;
        Edit1: TEdit;
        Button2: TButton;
        Label1: TLabel;
        Label2: TLabel;
        Memo2: TMemo;
        Edit2: TEdit;
        procedure Button1Click(Sender: TObject);
        procedure Button2Click(Sender: TObject);
      private
        { Private declarations }
        answers:TStringList;
        sum:integer;
        data:array[1..MAXLEN] of integer;
        answer: array[1..MAXLEN] of boolean;
        procedure SaveAnswer();
        procedure Question(const ipos:integer;const tsum:integer);
      public
        { Public declarations }
      end;var
      Form1: TForm1;procedure SortArray(var data: array of integer);implementation{$R *.dfm}
    //初始化
    procedure TForm1.Button1Click(Sender: TObject);
    var
      i:integer;
    begin
       Memo2.Lines.Clear;
       Randomize;
       sum:=integer(Random(200));
       Edit1.Text:=inttostr(sum);
       for i:=Low(data) to High(data) do
         begin
          answer[i]:=FALSE;
          Randomize;
          data[i]:=integer(Random(25))+1; //去除等于0的情况,可以优化速度。所以有0值时,应先去除0,算好后再把0项加上。
          Memo2.Lines.Add(inttostr(data[i]));
         end;
    end;//排序
    procedure SortArray(var data: array of integer);
    var
     i,j,k,temp:integer;
    begin
       for i:=Low(data) to High(data)-1 do
        begin
          k:=i;
          for j:=k+1 to High(data) do
            begin
              if data[j]<data[k] then
                 k:=j;
            end;
          if k<>i then
           begin
              temp:=data[k];
              data[k]:=data[i];
              data[i]:=temp;
           end;
        end;
    end;//存结果
    procedure TForm1.SaveAnswer();
    var
      i:integer;
      tempstr:string;
    begin
      tempstr:='';
      for i:=Low(answer) to High(answer) do
        if answer[i] then
    //      tempstr:=tempstr+inttostr(data[i])+' '; //此处耗时
      answers.Add(tempstr); //此处耗时
    end;//递归求值
    procedure TForm1.Question(const ipos:integer;const tsum:integer);
    begin
      if ipos>High(data) then
        exit;
      if(data[ipos]=tsum) then
        begin
           answer[ipos]:=True;
           SaveAnswer();
           Question(ipos+1,0);
           answer[ipos]:=false;
           Question(ipos+1,tsum);
        end
       else if(data[ipos]<tsum) then
        begin
           answer[ipos]:=True;
           Question(ipos+1,tsum-data[ipos]);
           answer[ipos]:=false;
           Question(ipos+1,tsum);
        end
       else
        exit;
    end;//main
    procedure TForm1.Button2Click(Sender: TObject);
    var
      i,tsum:integer;
      tstart,tend:TDateTime;
    begin
       tsum:=0;
       Memo1.Lines.Clear;
       Edit2.Text:='';
       answers:=TStringList.Create;
       for i:=Low(data) to High(data) do
          tsum:=tsum+data[i];
       if(tsum>=sum) then
        begin
         SortArray(data);
         tstart:=time;
         Question(Low(data),sum);
         tend:=time;
        end;
       Edit2.Text:=inttostr(answers.Count);
       //Memo1.Lines.AddStrings(answers); //此处耗时
       showMessage(floattostr(MilliSecondsBetween(tend,tstart))+'ms');
       answers.Free;
    end;end.
      

  6.   

    不就是排列组合吗? C[N,m]的复杂度要想快,换机器!
      

  7.   

    to SuperZysoft() ( ) 
    能把你那高效的代码贴出来看看吗?牛皮可不是吹得哟,有...贴出瞧瞧。