I have a vector of size = N where each element i can have values from 0 to possible_values[i]-1. I want to do a function that iterates me through all those values.
I was
EDIT: A bit more concise general code with better comments and explanation (I hope ;)).
This is an iterative, not a recursive, approach for an arbitrary number of positions with arbitrary maximum possible values. The idea is as follows.
We are given maximum possible value in each position. For each position we generate an array containing of all possible values for this position. We find total number of combinations of how these values can be picked out to fill in positions ("number of permutations", equal to product of all possible values). We then iterate through all combinations, storing each current combination in an array of combinations, and updating current indices to select next combination on the next iteration. We don't need to worry about boundary checks, because we are inherently limited by number of combinations. After iterated through all combinations, we return a 2D array that holds all of them (and then print them).
Hope it might be useful (code on ideone.com):
#include
#include
#include
namespace so {
using size = std::size_t;
using array_1d = std::vector;
using array_2d = std::vector;
array_2d generate_combinations_all(array_1d const & _values_max) {
array_2d values_all_; // arrays of all possible values for each position
size count_combination_{1}; // number of possible combinations
for (auto i_ : _values_max) { // generate & fill in 'values_all_'
array_1d values_current_(i_);
size value_current_{0};
std::generate(values_current_.begin(), values_current_.end(), [&] {return (value_current_++);});
values_all_.push_back(std::move(values_current_));
count_combination_ *= i_;
}
array_2d combinations_all_; // array of arrays of all possible combinations
array_1d indices_(_values_max.size(), 0); // array of current indices
for (size i_{0}; i_ < count_combination_; ++i_) {
array_1d combinantion_current_; // current combination
for (size j_{0}; j_ < indices_.size(); ++j_) // fill in current combination
combinantion_current_.push_back(values_all_[j_][indices_[j_]]);
combinations_all_.push_back(std::move(combinantion_current_)); // append to 'combinations_all_'
for (size m_{indices_.size()}; m_-- > 0;) // update current indices
if (indices_[m_] < _values_max[m_] - 1) { // ++index at highest position possible
++indices_[m_];
break;
}
else indices_[m_] = 0; // reset index if it's alrady at max value
}
return (combinations_all_);
}
void print_combinations_all(array_2d const & _combinations_all) {
for (auto const & i_ : _combinations_all) { // "fancy" printing
std::cout << "[";
for (size j_{0}; j_ < i_.size(); ++j_)
std::cout << i_[j_] << ((j_ < i_.size() - 1) ? ", " : "]\n");
}
}
} // namespace so
int main() {
so::array_1d values_max_a_{3, 2, 2};
so::array_1d values_max_b_{2, 1, 3, 2};
so::print_combinations_all(so::generate_combinations_all(values_max_a_));
std::cout << "***************" << std::endl;
so::print_combinations_all(so::generate_combinations_all(values_max_b_));
return (0);
}
Program's output:
[0, 0, 0]
[0, 0, 1]
[0, 1, 0]
[0, 1, 1]
[1, 0, 0]
[1, 0, 1]
[1, 1, 0]
[1, 1, 1]
[2, 0, 0]
[2, 0, 1]
[2, 1, 0]
[2, 1, 1]
***************
[0, 0, 0, 0]
[0, 0, 0, 1]
[0, 0, 1, 0]
[0, 0, 1, 1]
[0, 0, 2, 0]
[0, 0, 2, 1]
[1, 0, 0, 0]
[1, 0, 0, 1]
[1, 0, 1, 0]
[1, 0, 1, 1]
[1, 0, 2, 0]
[1, 0, 2, 1]