我在此论坛里找到了一个高手写的函数如下,好象在排列组合问题中是效率非常高的了。
用Combination(Memo1.Lines, 'abcdefg', 6);的方法来调用它。
得到的结果为:
abcdef
abcdeg
abcdfg
abcefg
abdefg
acdefg
bcdefg
共七组,字符不重复出现的组合。
###问题:如果上述字符中的一个就代表一个字符串(如a为'13',b为'ac')的话,我该如何实现,或如何 修改以下函数?
###我希望的调用方式是:Combination(Memo1.Lines, '13 ab 56 cd ef tg 32 53 ee 12, 6);
function Combination(mStrings: TStrings; mStr: string;
  mLen: Integer): Boolean; { 组合 }
  procedure fCombination(mLeft, mRight: string);
  var
    I: Integer;
  begin
    if Length(mLeft) >= mLen then
      mStrings.Add(mLeft)
    else for I := 1 to Length(mRight) do
      fCombination(mLeft + Copy(mRight, I, 1), Copy(mRight, I + 1, MaxInt));
  end;
begin
  Result := False;
  if not Assigned(mStrings) then Exit; //判断 mStrings是否已赋值
  mStrings.BeginUpdate;
  try
    mStrings.Clear;
    fCombination('', mStr);
  finally
    mStrings.EndUpdate;
  end;
  Result := True;
end; { Combination }

解决方案 »

  1.   

    前人基础上略做修改如下:
    function Combination(mStrings: TStrings; mStr: string;
      mLen: Integer): Boolean; 
      procedure fCombination(mLeft, mRight: string);
      var
        I: Integer;
      begin
        if Length(mLeft) >= mLen*3-1 then
          mStrings.Add(mLeft)
        else for I := 1 to Length(mRight)  do
          fCombination(mLeft + Copy(mRight, I*3-2, 3), Copy(mRight, I*3-2 + 3, MaxInt));
      end;
    begin
      Result := False;
      if not Assigned(mStrings) then Exit; 
      mStrings.BeginUpdate;
      try
        mStrings.Clear;
        fCombination('', (mStr));
      finally
        mStrings.EndUpdate;
      end;
      Result := True;
    end; { Combination }
    procedure TForm1.BitBtn1Click(Sender: TObject);
    begin
        Combination(Memo1.Lines,'aa bb cc dd ee ff gg', 6);
    end;