生成未知长度的所有组合

时间:2016-09-24 13:44:57

标签: c++ cartesian-product

我正在编程,我在c ++中生成所有组合。我知道如何生成所有组合 一定的长度 我的结果是那样的

A A A
A A B
A A C
A B A
A B B
A B C
A C A
A C B
A C C
B A A
..... 

我的问题是,我不知道,如何生成未知长度的所有组合。例如,我希望字长= 5,程序将生成完全长度为5的所有组合。怎么做?

A A A A A
A A A A B
A A A A C
A A A B A
.........

(对不起我的英文)

3 个答案:

答案 0 :(得分:1)

请参阅链接Print all permutations with repetition of characters

页面中的以下递归函数可以创建最后+ 1个长度排列。

/* The main function that recursively prints all repeated 
permutations of  the given string. It uses data[] to store all
permutations one by one */
void allLexicographicRecur (char *str, char* data, int last, int index)
{
  int i, len = strlen(str);

  // One by one fix all characters at the given index and recur for 
  // the/ subsequent indexes
  for ( i=0; i<len; i++ )
  {
      // Fix the ith character at index and if this is not the last 
      // index then recursively call for higher indexes
      data[index] = str[i] ;

     // If this is the last index then print the string stored in
     // data[]
     if (index == last)
         printf("%s\n", data);
     else // Recur for higher indexes
        allLexicographicRecur (str, data, last, index+1);
  }
}

我认为这可以达到您的目的。 使用&#39; last&#39;的所需(长度为1)值调用 allLexicographicRecur 参数。

答案 1 :(得分:1)

这实际上只不过是计算

如果您有字母A,B和C,则以3为基数 A为0,B为1,C为2。

又快又脏:

#include <string>
#include <iostream>

int main()
{
    for(int i = 0; i < 100; i++) {
        const int base = 3;
        const char zero_char = 'A';
        const size_t length = 5;
        std::string out;
        for(int n = i; n > 0; ) {
            int d = n%base;
            out = static_cast<char>(zero_char + d) + out;
            n /= base;
        }
        while(out.length() < length) out = zero_char + out;
        std::cout << out << '\n';
    }
}

see it live

可能的组合是 base length ,因此如果您希望A,B,C的所有组合都有5位数,请更改第一个{{1}的限制}循环到3 5 (= 243):

for

答案 2 :(得分:0)

您可以使用以下内容:

bool increase(const std::string& s, std::vector<std::size_t>& it)
{
    for (std::size_t i = 0, size = it.size(); i != size; ++i) {
        const std::size_t index = size - 1 - i;
        ++it[index];
        if (it[index] >= s.size()) {
            it[index] = 0;
        } else {
            return true;
        }
    }
    return false;
}

void do_job(const std::string& s,
            const std::vector<std::size_t>& it)
{
    for (std::size_t i = 0; i != it.size(); ++i) {
        std::cout << s[it[i]] << " ";
    }
    std::cout << std::endl;
}

void cartesian_product(const std::string& s, std::size_t n)
{
    std::vector<std::size_t> it(n, 0u);

    do {
        do_job(s, it);
    } while (increase(s, it));
}

Demo