Почему перестановочные функции STL здесь не работают? - PullRequest
0 голосов
/ 25 января 2020
#include <iostream>
#include <algorithm>

int main()
{
    int a[3] = {2, 1, 3};
    auto printArray = [&a]() -> void
    {
        for (const auto& e : a) std::cout << " " << e;
        std::cout << "\n";
    };

    // My doubts are here
    while (std::prev_permutation(a, a + 3)) printArray();
    while (std::next_permutation(a, a + 3)) printArray();

    return 0;
}

Вывод:

1 3 2

1 2 3

Но я думал, что вывод будет быть:

1 3 2

1 2 3

1 3 2

2 1 3

2 3 1

3 1 2

3 2 1

Похоже, что звонок next_permutation здесь никогда не происходит, но почему?

Ответы [ 2 ]

2 голосов
/ 25 января 2020

Вы можете std::reverse массив после последнего вызова std::prev_permutation:

int main()
{
    std::array<int, 3> a {2, 1, 3};

    using std::begin; using std::end;

    while (std::prev_permutation(begin(a), end(a))) {
        std::cout << a << std::endl;
    }
    std::reverse(begin(a), end(a));
    assert(std::is_sorted(begin(a), end(a)));
    while (std::next_permutation(begin(a), end(a))) {
        std::cout << a << std::endl;
    }
}

Live On Coliru

0 голосов
/ 25 января 2020

Вы можете передать функцию сравнения. В этом примере я передал функцию сравнения, содержащую счетчик:

#include <iostream>
#include <algorithm>

int main()
{
    std::array<int, 3> a = {2, 1, 3};
    auto printArray = [&a]() -> void
    {
        for (const auto& e : a) std::cout << " " << e;
        std::cout << "\n";
    };

    // My doubts are here
    while (std::prev_permutation(std::begin(a), std::end(a))) printArray();
    while (std::next_permutation(std::begin(a), std::end(a), [](const auto &, const auto &) {
        static std::size_t i = 2 * 6 + 1;
        if (i != 0) --i;
        return i != 0;
    })) printArray();

    return 0;
}

Для каждой перестановки существует два сравнения.

...