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

问题描述 投票:2回答:1

这个问题是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定义。

c++ combinatorics cartesian-product
1个回答
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

© www.soinside.com 2019 - 2024. All rights reserved.