C++ 从集合列表中删除重复项

C++ 从集合列表中删除重复项,c++,algorithm,std,C++,Algorithm,Std,我正在实现著名的“集合子集”问题。我想我得到了一个很好的工作解决方案,但它包含重复项。我希望list.unique()能够适应这种情况,但是因为对于集合,没有定义==运算符,所以它不起作用。一组集合也不能修复这种情况(现在使用集合列表) 有了80%的完整解,我意识到有一个比我带来的更好的算法。但我想知道是否有一种聪明的方法可以在不完全重写算法的情况下删除重复项 这是我的密码: MAIN.CPP: #include "random.hpp" using namespace std; int m

我正在实现著名的“集合子集”问题。我想我得到了一个很好的工作解决方案,但它包含重复项。我希望list.unique()能够适应这种情况,但是因为对于集合,没有定义==运算符,所以它不起作用。一组集合也不能修复这种情况(现在使用集合列表)

有了80%的完整解,我意识到有一个比我带来的更好的算法。但我想知道是否有一种聪明的方法可以在不完全重写算法的情况下删除重复项

这是我的密码:

MAIN.CPP:

#include "random.hpp"

using namespace std;

int main(void) {

    subsets2();

    getchar();
    return 0;
}
Random.Cpp:

void getSubsets2(set<int> myset, list<set<int> > * ptr, int length) {

    if (length == 1) {
        ptr->push_back(myset);
    }

    else {
        set<int> second(myset);
        set<int>::iterator it;
        ptr->push_back(myset);

        it = myset.begin();
        myset.erase(it);
        it = second.begin();
        ++it;
        second.erase(it);

        getSubsets2(myset, ptr, length - 1);
        getSubsets2(second, ptr, length - 1);
    }
}

void subsets2(void) {
    const int N = 4;
    int myints[N] = {
        88, 33, 23, 22
    };
    set<int> myset(myints, myints + N);
    set<int> set2;

    list<set<int> > mylist;

    list<set<int> > * ptr;
    ptr = & mylist;

    list<set<int> > ::iterator it;
    set<int>::iterator it2;

    getSubsets2(myset, ptr, N);
    mylist.unique();


    for (it = mylist.begin(); it != mylist.end(); ++it) {
        set2 = * it;
        for (it2 = set2.begin(); it2 != set2.end(); ++it2) {
            cout << * it2 << " ";
        }
        cout << "\n";
    }

}
Unique()从容器中删除所有连续的重复元素。因此,在运行unique()之前,需要先对mylist进行排序


另一种方法是为所有标准容器定义
std::less
。因此,我们可以定义如下:

std::set<std::set<int>, std::less<std::set<int>>> set_of_sets;
std::集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合;
这将自动过滤出重复的集合。一个完整的例子:

#include <set>
#include <vector>
#include <iostream>
#include <functional>

int main()
{
    std::vector<std::vector<int>> x = {{1,2,3}, {1,2}, {1,2,3}, {4,5,6},
                                       {4,5}, {5,6}, {4,5,6}};
    std::set<std::set<int>, std::less<std::set<int>>> set_of_sets;

    for(auto it = x.begin(); it != x.end(); ++it) {
        std::set<int> s;
        s.insert(it->begin(), it->end());
        set_of_sets.insert(s);
    }

    for(auto it = set_of_sets.begin(); it != set_of_sets.end(); ++it) {
        std::cout << "{";
        for(auto it2 = it->begin(); it2 != it->end(); ++it2) {
            std::cout << *it2 << ", ";
        }
        std::cout << "}\n";
    }

    return 0;
}
#包括
#包括
#包括
#包括
int main()
{
向量x={1,2,3},{1,2},{1,2,3},{4,5,6},
{4,5}, {5,6}, {4,5,6}};
std::集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合集合;
用于(自动it=x.begin();it!=x.end();+it){
std::集s;
s、 插入(it->begin(),it->end());
集合的集合。插入;
}
for(auto it=set of _set.begin();it!=set of _set.end();++it){
std::cout begin();it2!=it->end();+it2){

std::cout使用字符串列表存储最终结果:

    list<string> uniq_list;
    for (it = mylist.begin(); it != mylist.end(); ++it) {
        set2 = * it; 
        stringstream ss; 
        for (it2 = set2.begin(); it2 != set2.end(); ++it2) {
            ss << * it2 << " ";
        }
        uniq_list.push_back(ss.str());
    }   
    uniq_list.sort();
    uniq_list.unique();
    for (list<string>::iterator it=uniq_list.begin(); it != uniq_list.end(); it++){
      cout << *it << endl;
    }
list uniq\u list;
for(it=mylist.begin();it!=mylist.end();+it){
set2=*it;
细流ss;
对于(it2=set2.begin();it2!=set2.end();+it2){

ss还有一个
模板void unique(BinaryPredicate binary_pred);
为列表定义。当然,unique只删除元素“next”删除重复项听起来像是解决更严重问题的绷带。为什么您的代码首先要创建重复项?解决此问题的好算法应该避免完全创建重复项。
#include <set>
#include <vector>
#include <iostream>
#include <functional>

int main()
{
    std::vector<std::vector<int>> x = {{1,2,3}, {1,2}, {1,2,3}, {4,5,6},
                                       {4,5}, {5,6}, {4,5,6}};
    std::set<std::set<int>, std::less<std::set<int>>> set_of_sets;

    for(auto it = x.begin(); it != x.end(); ++it) {
        std::set<int> s;
        s.insert(it->begin(), it->end());
        set_of_sets.insert(s);
    }

    for(auto it = set_of_sets.begin(); it != set_of_sets.end(); ++it) {
        std::cout << "{";
        for(auto it2 = it->begin(); it2 != it->end(); ++it2) {
            std::cout << *it2 << ", ";
        }
        std::cout << "}\n";
    }

    return 0;
}
    list<string> uniq_list;
    for (it = mylist.begin(); it != mylist.end(); ++it) {
        set2 = * it; 
        stringstream ss; 
        for (it2 = set2.begin(); it2 != set2.end(); ++it2) {
            ss << * it2 << " ";
        }
        uniq_list.push_back(ss.str());
    }   
    uniq_list.sort();
    uniq_list.unique();
    for (list<string>::iterator it=uniq_list.begin(); it != uniq_list.end(); it++){
      cout << *it << endl;
    }