【问题标题】:how to get all the possible combinations of vector c++如何获得向量c ++的所有可能组合
【发布时间】:2016-05-07 14:47:32
【问题描述】:

我有一个问题,我已经挣扎了好几个小时来解决它,但我找不到方法。

我有一个vector<vector<string>> mat,我不知道它的大小,我唯一知道的是每个向量上有相同数量的字符串。现在,我想做的是获取这些字符串的所有可能组合,例如: 想象一下 mat.size() = 3 和 mat[0].size() = 3(记住,所有的向量都有相同数量的字符串,所以不管是 make mat[0].size() 还是 mat[3].size() )我想要的是让所有的字符串都打开这个职位

0,0 0,1 0,2  
0,0 0,1 1,2
0,0 0,1 2,2
0,0 1,1 0,2 
0,0 1,1 1,2
0,0 1,1 2,2
0,0 2,1 0,2
0,0 2,1 1,2
0,0 2,1 2,2
1,0 0,1 0,2

等等……

每一行都将存储在一个新的数组/向量中

有什么想法吗?

编辑(以防万一不是很清楚):

假设mat 有下一个数据:

mat[0] ={aa,bb,cc}
mat[1] ={dd,ee,ff}
mat[2] ={gg,hh,ll}

我想以某种方式得到的是:

aa,bb,cc
aa,bb,ff
aa,bb,ll
aa,ee,cc
aa,ee,ff
aa,ee,ll
aa,hh,cc
aa,hh,ff
aa,hh,ll

等等……

【问题讨论】:

  • std::next_permutation 怎么样?
  • 我没有得到你的问题。您想要组合存储在 mat 中的所有字符串吗?
  • 要应用 Joachim 的建议,创建一个 size_t 的向量,其值为 0 到 mat.size() * mat[0].size() - 1(按此顺序),然​​后在该向量上调用 next_permutation .使用向量中的每个索引 i 来表示 mat[i / mat.size()][i % mat[0].size()]。或者,只是先将mat中的所有字符串复制到一个新的一维向量中,然后置换它....

标签: c++ permutation


【解决方案1】:
vector<vector<string>> mat; // each interior vector has the same length
// populate mat somehow...

size_t width = mat.at(0).size();
vector<string> out(pow(mat.size(), width);

// each value of first column is repeated (rows^(cols-1)) times
size_t reps = out.size(); 
for (size_t col = 0; col < width; ++col) {
    reps /= width;
    for (size_t ii = 0; ii < out.size(); ++ii) {
        if (ii != 0) {
            out[ii].append(',');
        } else {
            out[ii].reserve(2 * width); // performance optimization
        }
        size_t row = ii / reps % mat.size();
        out[ii].append(mat[row][col]); // write one cell of output
    }
}

如果我们事先知道字符串有一些固定长度,我们可以优化reserve() 调用,但我只是假设每个字符串至少有一个字符。

【讨论】:

    【解决方案2】:

    您基本上希望矩阵的每一列都有一个嵌套的 for 循环。但是由于列数是动态的,所以你不能真正做到这一点。您可以做的是使用递归函数,其中包含一个 for 循环,该循环遍历行,并根据参数选择列,该参数在每次递归调用时递增。像这样的:

    void permute_impl(size_t width, std::vector<std::vector<int>> const &mat,
                      size_t column, std::vector<int> &prefix) {
      if (column < width) {
        for (auto &row : mat) {
          prefix.push_back(row[column]);
          permute_impl(width, mat, column + 1, prefix);
          prefix.pop_back();
        }
      } else {
        for (auto i : prefix)
          std::cout << i << ' ';
        std::cout << '\n';
      }
    }
    
    void permute(std::vector<std::vector<int>> const &mat) {
      if (mat.empty())
        return;
      std::vector<int> prefix;
      size_t N = mat[0].size();
      // assert that all rows are the same size
      for (auto &row : mat)
        assert(row.size() == N);
      permute_impl(N, mat, 0, prefix);
    }
    

    DEMO

    【讨论】:

      【解决方案3】:

      我没有时间解决这个问题,但我尝试了 10 分钟,我想我可以回答你的问题。我认为您想找到所有可能的组合。所以我的解决方案是这样的:

      #include <iostream>
      #include <vector>
      #include <queue>
      
      using namespace std;
      
      // I define the vector<int> data type to be stored in the variable int_vector.
      typedef vector<int> int_vector;
      
      // The definition of the max index of the array.
      #define N 3
      
      // The Solve class.
      class Solve{
          public:
              // The elements of an array! This is just for testing!
              const int num[N] = {1, 2, 3};
              // The length of the array. That means the index of the last element.
              const int length = N - 1;
              // The vector that stores the possible combinations.
              vector<int_vector> solution;
      
              // The create_combination function.
              void create_combinations(){
      
                  // The queue to create the possible combinations.
                  queue<int_vector> combinations;
      
                  // A vector just to store the elements.
                  vector<int> test;
      
                  // I create the front vector of the queue.
                  for(int i = 0; i <= length; i++){
                      // I push back to the vector the i-element of the num array.
                      test.push_back(num[i]);
                  }
      
                  // I push back to the queue the test vector.
                  combinations.push(test);
      
                  // This is just a variable to store some numbers laterin the loop.
                  int number;
                  // This loop runs forever EXCEPT if the condition that is refered in the if-statement later in te loop happens.
                  while(1){
                      // This creates the possible combinations and push them back to the solution variable.
                      for(int sub_i = 0; sub_i <= length - 1; sub_i++){
                          // I access the front element of the queue.
                          test = combinations.front();
                          number = test[sub_i];
                          test.erase(test.begin() + sub_i);
                          test.push_back(number);
                          combinations.push(test);
                          solution.push_back(test);
                      }
                      // The pop function erases the front element of the queue. That means that the next element of the queue becomes the front of the queue.
                      combinations.pop();
                      //This is the condition that breaks the loop if it is true.
                      if(combinations.front()[2] == num[2]){
                          break;
                      }
                  }   
              }
      };
      
      // The main function.
      int main(){
          // I create the object of the Solve class.
          Solve solve;
          // I call the create_combinations function of the Solve class.
          solve.create_combinations();
          // I access the solution variable of the Solve class and I store it to another variable called combinations.
          vector<int_vector> combinations = solve.solution;
          // This loop prints out to the screen the possible combinations
          for(int i = 0; i <= 5; i++){
              for(int sub_i = 0; sub_i <= solve.length; sub_i++){
                  cout << combinations[i].at(sub_i) << " ";
              }
              cout << endl;
          }
      
          return 0;
      }
      

      如您所见,我使用队列解决了它,并将组合存储在向量中。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-12-15
        • 2012-11-25
        • 1970-01-01
        • 2019-10-25
        • 2013-02-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多