5

まず第一に、私の英語が下手ですみません。str: TStringList (Xn, Yn) からシンボルの組み合わせを生成しようとしています。ここで、X は新しい単語の文字の位置、Y は位置の変数です。
たとえば、私の StringList が持っているとしましょう

str[0]: '013456789'          
str[1]: 'abcdef'
str[2]: '5421'


この場合、216 語 (長さ (str[0]) * 長さ (str[1]) * 長さ (str[2])) を期待します。結果は次のようになります。

str[0][1]+ str[1][1]+ str[2][1] -> 0a5
str[0][1]+ str[1][1]+ str[2][2] -> 0a4
str[0][1]+ str[1][1]+ str[2][3] -> 0a2
str[0][1]+ str[1][1]+ str[2][4] -> 0a1

str[0][1]+ str[1][2]+ str[2][1] -> 0b5
str[0][1]+ str[1][2]+ str[2][2] -> 0b4
str[0][1]+ str[1][2]+ str[2][3] -> 0b2
str[0][1]+ str[1][2]+ str[2][4] -> 0b1

str[0][1]+ str[1][3]+ str[2][1] -> 0c5
str[0][1]+ str[1][3]+ str[2][2] -> 0c4
str[0][1]+ str[1][3]+ str[2][3] -> 0c2
str[0][1]+ str[1][3]+ str[2][4] -> 0c1

などなど

str[0][10]+ str[1][6]+ str[2][3] -> 9f2 
str[0][10]+ str[1][6]+ str[2][4] -> 9f1

今、私は「FOR」ループを作成して、可能なすべての単語の cicles を作成する方法を混乱させています。

よろしくマーティン

4

2 に答える 2

3

これは再帰で行うことができます。

procedure Recurse(startIx,stopIx: Integer; prefix: String; const aList: TStringList);
var
  ch : Char;
begin
  if (startIx > stopIx) then begin
    WriteLn(prefix);
  end
  else
  begin
    for ch in aList[startIx] do begin
      Recurse( startIx+1,stopIx,prefix + ch,aList);
    end;
  end;
end;

Recurse(0,str.Count-1,'',str);

再帰は最初は魔法のように思えるかもしれませんが、この種の組み合わせ論を解決するための非常に効果的な方法です。

この問題の解決策は、Cartesian product.

古いバージョンの Delphi を使用している場合は、次のように文字を繰り返します。

procedure Recurse(startIx,stopIx: Integer; prefix: String; const aList: TStringList);
var
  i : Integer;
begin
  if (startIx > stopIx) then begin
    WriteLn(prefix);
  end
  else
  begin
    for i := 1 to Length(aList[startIx]) do begin
      Recurse( startIx+1,stopIx,prefix + aList[startIx][i],aList);
    end;
  end;
end;
于 2013-11-03T14:19:12.443 に答える
1

3 つの for ループを一緒にネストする必要があります。str 配列のインデックスはゼロから始まりますが、2 番目の次元のインデックスは 1 から始まると仮定します。

var i,j,k:integer;

begin
    s = '';
    for i:=1 to length(str[0]) do
        for j:=1 to length(str[1]) do
            for k:=1 to length(str[2]) do
            begin
                combination := str[0][i]+str[1][j]+str[2][k];
                s := s + combination + chr(13) + chr(10);
            end;
    { you have all combinations in string s }
end;

可変数の文字長が必要な場合は、次のように実装できます。

procedure TForm1.FormCreate(Sender: TObject);
var str: array [0..10] of string;
    lengths : array [0..10] of integer;
    combination : string;
    index: array [0..10] of integer;
    n, i,j : integer;
    maxn : integer;
begin
    n := 3; { actual number of charaters in output word }
    str[0]:= '013456789';
    str[1]:= 'abcdef';
    str[2]:= '5421';


    { lengths will be used often later so they will be determined one time }
    for i:=0 to n-1 do lengths[i] := length(str[i]);
    maxn := 1; { maxn will be used to determine how meny iterations to make }
    for i:=0 to n-1 do maxn := maxn * lengths[i];
    { start at index 1 (first character) with each character position }
    for i:=0 to n-1 do index[i]:=1;


    memo1.Lines.Add(inttostr(maxn));

    { iterate all possibilities }
    for i:=1 to maxn do
    begin
      { start creating a combination }
      combination:='';
      for j:=0 to n-1 do
      begin
        combination := combination + str[j][index[j]];
      end;
      memo1.Lines.Add(combination);
      { increment indexes, from last to the first }
      for j:=n-1 downto 0 do
      begin
        index[j] := index[j]+1;
        { if index is in bounds of character posibilities stop incremented indexes,
          otherwise reset the index and increment next one }
        if index[j]<=lengths[j] then
        begin
            break; { stop incrementing indexes }
        end else begin
            index[j] := 1; { reset the index }
            { the loop will continue incrementing previous index }
        end;
      end;
    end;
end;

文字インデックスに固定変数を使用する代わりに、i,j,kそれらを配列に格納できますindex。インデックスのインクリメントは、紙の上で 2 つの数字を手で足すときのように機能します。追加してみる

 999
+  1
----

アイデアを得るために。

于 2013-11-03T12:34:33.713 に答える