Как создать матрицу со всеми возможными перестановками из n наборов из 5 значений (с дубликатами) в C / C ++ - PullRequest
0 голосов
/ 12 октября 2018

Я, по сути, пытаюсь в c ++ создать матрицу (размеры (5 ^ n) x (n)), где каждая строка представляет собой возможную перестановку этих 5 значений: -2, -1,0,1,2,Например, если бы я хотел получить матрицу для 3 наборов этих значений, она бы выглядела следующим образом:

125 x 3

-2 -2 -2

-2 -2 -1

-2 -2 0

.,.

.,.

.,.

2 2 0

2 2 1

2 2 2

и матрица для 4 комплектов будет выглядеть так:

625 x 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

Другими словами, я пытаюсь реализовать "перманент" MATLABфункция в C ++.Я уверен, что это выполнимо с помощью рекурсивной функции каким-либо образом (с вектором целочисленных векторов для представления матрицы), но отследить правильное значение для размещения в правильном индексе сложно, чтобы обернуть мою голову.Любая помощь с этим будет принята с благодарностью.

1 Ответ

0 голосов
/ 12 октября 2018

Решение с использованием жесткого кода будет выглядеть следующим образом:

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);

Демо

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...