如何得到所有可能的向量c++的组合

how to get all the possible combinations of vector c++

本文关键字:向量 组合 c++ 有可能 何得      更新时间:2023-10-16

我遇到了一个问题,我已经花了几个小时的时间来解决它,但我找不到方法。

我有一个vector<vector<string>> mat,我不知道它的大小,我唯一知道的是每个向量上有相同数量的字符串。现在,我想做的是得到这些字符串的所有可能的组合,比如:假设mat.size()=3和mat[0].size()=3(记住,所有向量都有相同数量的字符串,所以无论是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

等等…

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()调用,但我只是假设每个字符串至少有一个字符。

您基本上想要为矩阵的每一列嵌套一个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);
}

演示

我没有时间解决这个问题,但我试了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;
}

正如你所看到的,我使用队列解决了它,并将组合存储在向量中。