0

I am trying to insert values into a set < set > container in c++, I am using an iterator to iterate through the outer set, and then attempting to simply call the insert function on the iterator after dereferencing. this is the current code:

for ( set<set<int>>::iterator new_it=subsetTemp.begin();new_it!=subsetTemp.end();new_it++){
        (*new_it).insert( num );
    }

Throws error of:

error: no matching function for call to ‘std::set<int>::insert(const int&) const’

and:

 error: cannot bind rvalue reference of type ‘std::set<int>::value_type&& {aka int&&}’ to lvalue of type ‘const int’

this is the full code:

set< set<int> > getAllSubsets(set<int> superset)
{
    set< set<int> > subset;
    set<int> empty;
    subset.insert( empty );

    for ( const int& supernum : superset){
        set< set<int> > subsetTemp = subset;  //making a copy of given 2-d set.

        for ( set<set<int>>::iterator new_it=subsetTemp.begin();new_it!=subsetTemp.end();new_it++){
            (*new_it).insert( supernum );   // adding set[i] element to each subset of subsetTemp. like adding {2}(in 2nd iteration  to {{},{1}} which gives {{2},{1,2}}.
        }

        for ( set<set<int>>::iterator new_it=subsetTemp.begin();new_it!=subsetTemp.end();new_it++){
            subset.insert( *new_it );  //now adding modified subsetTemp to original subset (before{{},{1}} , after{{},{1},{2},{1,2}}) 
        }
    }
    return subset;
}

the application is to get all subsets of a set - the function takes in a set e.g. {1,3,5}, and attempts to find all possible subsets of that set within a set e.g. { {1} , {1,3} , {3} .... {1,5} } , utilises the code from Finding all the subsets of a set

Thanks

Pdizzle
  • 1
  • 1
  • The elements of a `std::set` are `const`; you cannot modify them. Thus you cannot insert into `*new_it` because it refers to an element in a `std::set>`. – Miles Budnek May 26 '21 at 03:16

1 Answers1

1

The element of set can't be changed, think about this: On each change of the element, the order of the set may be changed(A set is an ordered container).

You may change the temporary container into a vector


#include <iostream>
#include <set>
#include <vector>
using namespace std;
set<set<int>> getAllSubsets(set<int> superset) {
  set<set<int>> subset;
  set<int> empty;
  subset.insert(empty);

  for (int supernum : superset) {
    vector<set<int>> subsetTemp(
        subset.begin(), subset.end());  // making a copy of given 2-d set.

    for (auto new_it = subsetTemp.begin(); new_it != subsetTemp.end();
         new_it++) {
      new_it->insert(supernum);  // adding set[i] element to each subset of
                                 // subsetTemp. like adding {2}(in 2nd iteration
                                 // to {{},{1}} which gives {{2},{1,2}}.
    }

    for (auto new_it = subsetTemp.begin(); new_it != subsetTemp.end();
         new_it++) {
      subset.insert(
          *new_it);  // now adding modified subsetTemp to original subset
                     // (before{{},{1}} , after{{},{1},{2},{1,2}})
    }
  }
  return subset;
}

Or simpler with the range for, and std::move to avoid unnecessary copy.

set<set<int>> getAllSubsets(const set<int>& superset) {
  set<set<int>> subset;
  set<int> empty;
  subset.insert(empty);

  for (int supernum : superset) {
    vector<set<int>> subsetTemp(subset.begin(), subset.end());
    for (auto& temp_inner_set : subsetTemp) {
      temp_inner_set.insert(supernum);
    }

    for (auto& temp_inner_set : subsetTemp) {
      subset.insert(std::move(temp_inner_set));
    }
  }
  return subset;
}

Online demo

prehistoricpenguin
  • 6,130
  • 3
  • 25
  • 42