【问题标题】:Generating all combinations with unknown length生成所有未知长度的组合
【发布时间】:2017-02-02 06:35:07
【问题描述】:

我正在练习编程,并在 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
.........

(对不起我的英语)

【问题讨论】:

  • 我们可以使用 C++ 来回答您的问题吗?编辑:抱歉,没有看到 for 循环初始化程序。
  • 这种类型的问题使用递归而不是迭代更容易解决。解决了递归算法后,再次将其转换为迭代算法。
  • "练习编程,我用c++生成所有组合" --> 那为什么要标记C?建议编辑以使用一种语言进行标记。一个好的答案可能取决于语言。
  • @IInspectable ,抱歉,我不知道该怎么做。请问,你能写一些伪代码吗?

标签: c++ cartesian-product


【解决方案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


可能的组合是baselength,因此如果您希望 A、B、C 的所有组合为 5 位数,请更改第一个 for 循环的限制到 35 (= 243):

for(int i = 0; i < 243; i++)

【讨论】:

    【解决方案2】:

    查看链接Print all permutations with repetition of characters

    页面中的以下递归函数,可以创建last+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);
      }
    }
    

    我认为这可以达到您的目的。 使用 'last' 参数所需的 (length-1) 值调用 allLexicographicRecur

    【讨论】:

      【解决方案3】:

      你可以使用类似的东西:

      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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-06-06
        • 2020-05-30
        • 2011-02-19
        • 1970-01-01
        • 1970-01-01
        • 2017-07-10
        • 2023-03-18
        相关资源
        最近更新 更多