如果不共享您的代码,我们只能猜测您的代码做错了什么。
这就是我所做的。我将差异逻辑包装在一个助手 operator- 中。我故意使用std::unordered_set,因为它们不能直接在std::set_difference中使用。
#include <algorithm>
#include <iostream>
#include <iterator>
#include <string>
#include <unordered_set>
#include <vector>
using std::cout;
using std::inserter;
using std::ostream;
using std::set_difference;
using std::sort;
using std::string;
using std::unordered_set;
using std::vector;
namespace {
unordered_set<string> operator-(unordered_set<string> const& minuend, unordered_set<string> const& subtrahend) {
vector<string> m(minuend.begin(), minuend.end());
vector<string> s(subtrahend.begin(), subtrahend.end());
sort(m.begin(), m.end());
sort(s.begin(), s.end());
unordered_set<string> diff;
set_difference(m.begin(), m.end(), s.begin(), s.end(), inserter(diff, diff.begin()));
return diff;
}
ostream& operator<<(ostream& out, unordered_set<string> const& container) {
char const* sep = " ";
out << "{";
for (auto const& s : container) {
out << sep << "\"" << s << "\"";
sep = ", ";
}
out << " }";
return out;
}
}
int main() {
auto a = unordered_set<string>{ "car", "boat", "table", "ball" };
auto b = unordered_set<string>{ "car", "goat", "helicopter" };
auto c = unordered_set<string>{ "square", "car", "goat", "boat" };
auto d = a - b - c;
cout << d << "\n";
}
更新回答 Fareanor 的问题
你为什么使用 std::unordered_set(而不是 std::set)?
我选择了 unordered_set 来证明 set_difference 需要一个有序的容器。 unordered_set 缺少该功能。
原始海报,在原始未经编辑的问题中,没有提供使用哪种容器的详细信息。
为什么要将它转换成需要排序的 std::vector(而不是转换成 std::set)?
向量是一个非常有效的容器,因为其中的元素具有局部性,因此具有良好的缓存。这是我的首选容器。
一个集合有更多的内存分配,因为它是一个节点网格,并且缺乏局部性。
无论如何,包含的字符串对象可能缺少局部性,因为它基本上是一个指向字符数组的智能指针。但由于小字符串优化 (SSO) 和这些都是小字符串,它也不会在堆外分配。
在原发帖人的场景中,每个容器中只有几件物品,因此效率问题可以忽略不计。但值得考虑的是,如果问题域扩大了。
我认为你应该使用 std::set (至少没有来自 OP 的任何澄清),如果用户得到一个 std::unordered_set ,则由他将其转换为适当的 std ::set 然后打电话给你的operator-()。
这是一个可行的选择。由于当时缺乏上下文,我认为这是“更糟糕的情况”,因为 unordered_set 容器不满足 set_difference 算法的要求。