HiveBrain v1.2.0
Get Started
← Back to all entries
patterncppMinor

Building a set of all subsets recursively in C++

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
allsubsetsbuildingrecursivelyset

Problem

Here is my recursive implementation of a power set function in C++. One thing that concerns me is that I am iterating over the set of sets while modifying its size. The code nevertheless functions as desired. Any feedback would be highly appreciated.

#include 
#include 
#include 

template 
void power_set(int i, const std::vector& set, std::set>& set_of_sets)
{
    if (i == set.size())
    {
        set_of_sets.emplace(std::set());  // empty set
        return;
    }

    power_set(i + 1, set, set_of_sets);

    for (auto& subset : set_of_sets)
    {
        auto augmented_subset = subset;
        augmented_subset.insert(set[i]);
        set_of_sets.insert(augmented_subset);
    }

}

int main()
{
    std::vector set = {"a", "b", "c"};
    std::set> set_of_sets;
    power_set(0, set, set_of_sets);

    for (auto& subset : set_of_sets)
    {
        std::cout << "{";
        for (auto& i : subset) std::cout << i << ",";
        std::cout << "}\n";
    }
    std::cout << set_of_sets.size() << "\n";
}

Solution

The recursion - even simulated via std::stack - is indeed unnecessary. Each subset has a corresponding number in \$[0, 2^n)\$ with bits indicating presence of an element in the subset, and each number in \$[0, 2^n)\$ corresponds to a subset. Consider a pseudocode

Set power_set(Set& the_set)
{
    Set result;
    Integral n = the_set.size()
    for (i = 0; i < (1 << n); i++) {
        result.insert(make_subset(the_set, i);
    }
    return result;
}

Set make_subset(Set& the_set, Integral indicator)
{
    Set result;
    Integral n = the_set.size();
    for (i = 0; i < (1 << n); i <<= 1) {
        if (indicator & i) {
            result.insert(the_set[i]);
        }
    }
    return result;
}

Code Snippets

Set power_set(Set& the_set)
{
    Set result;
    Integral n = the_set.size()
    for (i = 0; i < (1 << n); i++) {
        result.insert(make_subset(the_set, i);
    }
    return result;
}

Set make_subset(Set& the_set, Integral indicator)
{
    Set result;
    Integral n = the_set.size();
    for (i = 0; i < (1 << n); i <<= 1) {
        if (indicator & i) {
            result.insert(the_set[i]);
        }
    }
    return result;
}

Context

StackExchange Code Review Q#152464, answer score: 3

Revisions (0)

No revisions yet.