[英]Removing Duplicates from a list of sets
I am implementing the famous "subsets of a set" problem. 我正在实现着名的“一组子集”问题。 I think I got a good working solution, but it contains duplicates.
我认为我有一个很好的工作解决方案,但它包含重复项。 I was hoping that list.unique() would take of the situation, but since for a set the == operator isn't defined, it doesn't work.
我希望list.unique()能够处理这种情况,但是因为对于一个set没有定义==运算符,所以它不起作用。 A set of sets doesn't fix the situation either (using list of sets now).
一组集合也不能解决这种情况(现在使用集合列表)。
Having 80% complete solution, I realize there is a better algorithm out there than one I came with. 有80%的完整解决方案,我意识到有一个比我带来的更好的算法。 But I am wondering if there is a clever way to remove the duplicates without completely rewriting the algorithm?
但我想知道是否有一种聪明的方法来删除重复项而不完全重写算法?
Here's my code: 这是我的代码:
MAIN.CPP: main.cpp中:
#include "random.hpp"
using namespace std;
int main(void) {
subsets2();
getchar();
return 0;
}
Random.Cpp: 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";
}
}
Output: 输出:
22 23 33 88
23 33 88
33 88
88
33
23 88
88
23
22 33 88
33 88
88
33
22 88
88
22
Unique() removes all consecutive
duplicate elements from the container. Unique()从容器中删除所有
consecutive
重复元素。 So need to do sort mylist first before run unique(). 因此,在运行unique()之前需要先对mylist进行排序。
mylist.sort();
mylist.unique();
Just as another way of doing this, std::less<T>
is defined for all standard containers. 正如另一种方法,为所有标准容器定义了
std::less<T>
。 Hence, we can define something like: 因此,我们可以定义类似的东西:
std::set<std::set<int>, std::less<std::set<int>>> set_of_sets;
This will automatically filter out duplicate sets. 这将自动过滤掉重复的集合。 A full example:
一个完整的例子:
#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;
}
Using a string list to store final results: 使用字符串列表存储最终结果:
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;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.