如何生成任意数量的向量的组合组合

时间:2017-12-21 23:25:21

标签: c++ combinatorics cartesian-product

这个问题是kind of asked before,但我不确定是否真的提供了令人满意的答案。对我来说,我对std::vector std::string本身,而不是std::tuple感兴趣。

例如,如果我有std::vector<A>std::vector<B>std::vector<C>,那么我希望std::vector<std::tuple<A, B, C>>。或者,即使std::set<std::tuple<A, B, C>>,如果那更合适。

现在,我可以对嵌套的for循环进行编码,但是,如果可能的话,我想通过函数,模板函数来实现这一点,然后我认为variadic是完成任务所必需的。

无法保证ABC彼此之间有任何关系,更不用说转换为std::string了,正如一对夫妇所提议的那样回应。

我想说可以有一个可变的解决方案,但我不确定如何撰写std::vector<T>std::vector<T>::value_type定义。

1 个答案:

答案 0 :(得分:3)

如果要计算异构向量的笛卡尔积,可以执行以下操作:

template <std::size_t N>
bool increase(const std::array<std::size_t, N>& sizes, std::array<std::size_t, N>& it)
{
    for (std::size_t i = 0; i != N; ++i) {
        const std::size_t index = N - 1 - i;
        ++it[index];
        if (it[index] >= sizes[index]) {
            it[index] = 0;
        } else {
            return true;
        }
    }
    return false;
}

template <typename F, std::size_t ... Is, std::size_t N, typename Tuple>
void apply_impl(F&& f,
                std::index_sequence<Is...>,
                const std::array<std::size_t, N>& it,
                const Tuple& tuple)
{
    f(std::get<Is>(tuple)[it[Is]]...);
}

template <typename F, typename ... Ts>
void iterate(F&& f, const std::vector<Ts>&... vs)
{
    constexpr std::size_t N = sizeof...(Ts);
    std::array<std::size_t, N> sizes{{vs.size()...}};
    std::array<std::size_t, N> it{{(vs.size(), 0u)...}};

    do {
        apply_impl(f, std::index_sequence_for<Ts...>(), it, std::tie(vs...));
    } while (increase(sizes, it));
}

Demo