生成基于任意的字符串和长度的字符组合 - 类似于排列组合、类似于、字符串、排列

2023-09-11 22:44:24 作者:爱情会有那么一天

这个问题被问过其他语言,但搜索打完不是德尔福。 看到这个问题:How以生成置换随着重复字符这个问题:Generate任意字母可达任意长度和所有组合这一个:How生成使用的字符集的固定长度字符串的组合? 所以这个问题是不是新的,但我有一个很难翻译任何这德尔福。

This question was asked before in other languages but not delphi after searching SO. see this question:How to Generate Permutations With Repeated Characters and this question: Generate all combinations of arbitrary alphabet up to arbitrary length and this one: How to generate combination of fix length strings using a set of characters? so the question is not new but I am having a hard time translating any of this to delphi.

我试图做的是生成的组合,做包括人物像这样的重复: 如果我们有字符的字符串(由用户指定):美国广播公司和我们要生成的三个人物我会得到(由用户指定也长)长度: AAA AAB AAC ABA ABB ABC ACA ACB ACC BAA BAB BAC等等...

What I'm trying to do is generate combinations that does include repeats of characters such as this: if we have a string of characters (specified by user): ABC and we want to generate length of three characters (also length specified by user) I would get: AAA AAB AAC ABA ABB ABC ACA ACB ACC BAA BAB BAC etc...

这code,似乎这样做,但在C ++中:

This code seems to do this but in C++:

int N_LETTERS = 4;
char alphabet[] = {'a', 'b', 'c', 'd'};

std::vector<std::string> get_all_words(int length)
{
  std::vector<int> index(length, 0);
  std::vector<std::string> words;

  while(true)
  {
    std::string word(length);
    for (int i = 0; i < length; ++i)
      word[i] = alphabet[index[i]];
    words.push_back(word);

for (int i = length-1; ; --i)
{ 
  if (i < 0) return words;
  index[i]++;
  if (index[i] == N_LETTERS)
    index[i] = 0;
  else
    break;
    }
  }
}

这似乎也做到这一点:

    #include <iostream>
    #include <string>
    #include <math.h>
    #include <stdio.h>
    #include <stdlib.h>
    using namespace std;

void displayPermutation(string permutation[], int length){
    int i;
    for (i=0;i<length;i++){
        cout<<permutation[i];
    }
    cout << endl;
}

void getPermutations(string operatorBank[], int operatorCount, 
        string permutation[],int permutationLength, int curIndex){
    int i;
    //stop recursion condition
    if(curIndex == permutationLength){
        displayPermutation(permutation,permutationLength);
    }
    else{
        for(i = 0; i < operatorCount; i++){
            permutation[curIndex] = operatorBank[i];
            getPermutations(operatorBank,operatorCount,permutation,
                permutationLength,curIndex+1);
        }
    }
}

int main ()
   {
       int operatorCount = 4;
       int permutationLength = 3;
       string operatorBank[] = {"+","-","*","/"};
       string permutation[] = {"","","",""}; //empty string
       int curIndex = 0;
       getPermutations(operatorBank,operatorCount,permutation,
                               permutationLength,curIndex);
   return 0;
   }

最接近我想要的德尔福在这里被发现,但不允许 AAA 例如: http://www.swissdelphicenter.ch/torry/show$c $ c.php?ID = 1032

和没有这不是功课的情况下,你都在猜测。没有其他动机,但只是学习。

And no this is not homework in case you are guessing. No other motive but just learning.

EDIT3: 删除了问题的所有不相干code,以方便其他人阅读,并得到以下问题的答案。下看的答案为2种不同的方法来完成这一点:通过使用一个计数器功能使用递归,另一个

Removed all irrelevant code from question to make it easier for other people to read it and get to the answers below. Look under answers for 2 different methods to accomplish this: one using recursion and the other by using a counter function.

推荐答案

不完全是按照你的输出顺序,而是下面的方式类似二进制数加起来顺序...

Not exactly following your sequence of output, but following a sequence similar to the way binary numbers add up...

0001 
0010 
0011 
0100 
...

这个想法很简单:在数组中循环索引值,表示使用在各自的位置上的字符组成的输出组合的字符串。没有递归必需的。

The idea is simple: loop index values in an array indicating which character to use at the respective position to compose the output combination string. No recursion required.

NextCombination更新索引数组,以便在下一个组合定义,只要不是所有的组合,形成它返回真。假的时候回到全0。

NextCombination updates the index array so the next combination is defined, it returns true as long as not all combinations are formed. False when back to all 0's.

DefineCombinations接受一个字符串的字符使用(例如'ABC'),合并的字符串的大小(例如:3):这会将以下顺序备忘录:

DefineCombinations accepts a string with chars to use (for example 'ABC') and a size of the combined string (eg: 3): this adds the following sequence to a memo:

AAA, AAB, AAC, ABA, ABB, ABC, ACA, ACB, ACC, BAA, BAB, BAC, BBA, BBB, BBC, BCA, BCB, BCC, CAA, CAB, CAC, CBA, CBB, CBC, CCA, CCB, CCC

适应你的愿望。

Adapt as you wish.

function TForm1.NextCombination(var aIndices: array of Integer; const MaxValue: Integer): Boolean;

var Index : Integer;

begin
  Result:=False;
  Index:=High(aIndices);

  while not(Result) and (Index >= Low(aIndices)) do
  begin
    if (aIndices[Index] < MaxValue) then
    begin
      { inc current index }
      aIndices[Index]:=aIndices[Index] + 1;
      Result:=True;
    end
    else
    begin
      { reset current index, process next }
      aIndices[Index]:=0;
      Dec(Index);
    end;
  end;
end;

procedure TForm1.DefineCombinations(const Chars: String; const Size: Integer);

var aIndices     : array of Integer;

    Index        : Integer;
    sData        : String;

begin
     try
        SetLength(sData, Size);
        SetLength(aIndices, Size);

        repeat
           for Index:=Low(aIndices) to High(aIndices) do
             sData[Index + 1]:=Chars[aIndices[Index] + 1];

           memo1.Lines.Add(sData);
        until not(NextCombination(aIndices, Length(Chars) - 1));

     finally
        SetLength(aIndices, 0);
        SetLength(sData, 0);
     end;
end;

让我知道如果我错过了原来的问题什么的。

Let me know if I missed something from the original question.