По сути, я пытаюсь создать в c ++ матрицу (размеры (5 ^ n) x (n)), где каждая строка представляет собой возможную перестановку этих 5 значений: -2, -1,0,1,2. Например, если бы я хотел получить матрицу для 3 наборов этих значений, это выглядело бы так:
125 х 3
-2 -2 -2
-2 -2 -1
-2 -2 0
. . .
. . .
. . .
2 2 0
2 2 1
2 2 2
и матрица для 4 наборов будет выглядеть так:
625 х 4
-2 -2 -2 -2
-2 -2 -2 -1
-2 -2 -2 0
. . . .
. . . .
. . . .
2 2 2 0
2 2 2 1
2 2 2 2
Другими словами, я пытаюсь реализовать функцию «permn» в MATLAB на C ++. Я уверен, что это выполнимо с помощью рекурсивной функции каким-либо образом (с вектором целочисленных векторов для представления матрицы), но отследить правильное значение для размещения в правильном индексе сложно, чтобы обернуть мою голову. Любая помощь с этим будет принята с благодарностью.
Решение жесткого кода будет:
for (int a1 : {-2,-1,0,1,2}) {
for (int a2 : {-2,-1,0,1,2}) {
for (int a3 : {-2,-1,0,1,2}) {
for (int a4 : {-2,-1,0,1,2}) {
for (int a5 : {-2,-1,0,1,2}) {
do_job5(a1, a2, a3, a4, a5);
}
}
}
}
}
Вы можете использовать следующее для более общего способа:
bool increase(std::size_t size, 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] > size) {
it[index] = 0;
} else {
return true;
}
}
return false;
}
template <typename F, typename T>
void self_cartesian_product(F&& f, const std::vector<T>& v, std::size_t N)
{
std::vector<std::size_t> it(N, 0);
do {
f(v, it);
} while (increase(v.size(), it));
}
С вызовом, аналогичным
self_cartesian_product([](const auto& v, const auto& indexes)
{
for (auto i : indexes) {
std::cout << v[i] << " ";
}
std::cout << std::endl;
},
std::vector<int>{-2, -1, 0, 1, 2},
3);
Других решений пока нет …