迭代计算集合或向量的幂集

Iteratively calculate the power set of a set or vector

本文关键字:向量 计算 集合 迭代      更新时间:2023-10-16

虽然有很多关于如何生成集合的实际幂集的例子,但我找不到任何关于迭代(如std::iterator)生成幂集的东西。我之所以喜欢这样的算法,是因为我的基集的大小。由于n元素集的幂集有2^n个元素,所以在实际计算该集时,我会很快耗尽内存。那么,有什么方法可以为给定集的幂集创建迭代器吗?这可能吗?

  • 如果更容易的话,创建int集合的迭代器就可以了——我可以将它们用作实际集合/向量的索引
  • 由于我实际上在std::vector上工作,如果必要的话,随机访问是可能的

使用Combinations and Permutations中的for_each_combination,可以轻松地遍历std::vector<AnyType>的幂集的所有成员。例如:

#include <vector>
#include <iostream>
#include "../combinations/combinations"
int
main()
{
    std::vector<int> v{1, 2, 3, 4, 5};
    std::size_t num_visits = 0;
    for (std::size_t k = 0; k <= v.size(); ++k)
        for_each_combination(v.begin(), v.begin()+k, v.end(),
            [&](auto first, auto last)
            {
                std::cout << '{';
                if (first != last)
                {
                    std::cout << *first;
                    for (++first; first != last; ++first)
                        std::cout << ", " << *first;
                }
                std::cout << "}n";
                ++num_visits;
                return false;
            });
    std::cout << "num_visits = " << num_visits << 'n';
}

这访问vector的每个幂集成员,并执行函子,函子只计算访问次数并打印出当前幂集:

{}
{1}
{2}
{3}
{4}
{5}
{1, 2}
{1, 3}
{1, 4}
{1, 5}
{2, 3}
{2, 4}
{2, 5}
{3, 4}
{3, 5}
{4, 5}
{1, 2, 3}
{1, 2, 4}
{1, 2, 5}
{1, 3, 4}
{1, 3, 5}
{1, 4, 5}
{2, 3, 4}
{2, 3, 5}
{2, 4, 5}
{3, 4, 5}
{1, 2, 3, 4}
{1, 2, 3, 5}
{1, 2, 4, 5}
{1, 3, 4, 5}
{2, 3, 4, 5}
{1, 2, 3, 4, 5}
num_visits = 32

我上面使用的语法是C++14。如果你有C++11,你需要更改:

[&](auto first, auto last)

至:

[&](std::vector<int>::const_iterator first, std::vector<int>::const_iterator last)

如果您在C++98/03中,则必须编写一个函子或函数来替换lambda。

for_each_combination函数不分配额外的存储空间。这一切都是通过将CCD_ 8的成员交换到范围CCD_。在对for_each_combination的每次调用结束时,向量保持其原始状态。

如果出于某种原因想要提前"退出"for_each_combination,只需返回true而不是false