说我有两个std::set<std::string>
。第一个old_options
需要与new_options
中包含的其他选项合并。我不能只使用std::merge
(好吧,我这样做,但不仅如此),因为我还会检查双打并相应地警告用户。为此,我有
void merge_options( set<string> &old_options, const set<string> &new_options )
{
// find duplicates and create merged_options, a stringset containing the merged options
// handle duplicated the way I want to
// ...
old_options = merged_options;
}
使用
更好吗?std::swap( merged_options, old_options );
或我的作业?
是否有更好的方法来过滤重复项并返回合并的set
,而不是连续调用std::set_intersection
和std::set_union
以检测欺骗并合并set
s ?我知道它比一次遍历慢,并且一次做两次,但这些设置很小(性能并不重要),我相信标准比我更信任我自己。
答案 0 :(得分:1)
鉴于(如你所说)性能在这里并不重要,我会使用赋值和双遍算法。它更简单,更容易理解;如果你真的需要它所获得的东西,那么它只值得使用像交换这样的“技巧”。
编写自己的算法并不是一件坏事,但同样,除非你真正使用它提供的好处,否则我不会打扰。
答案 1 :(得分:1)
有什么问题
void merge_options( set<string> &old_options, const set<string> &new_options )
{
for (set<string>::iterator i = new_options.begin();
i != new_options.end(); ++i)
if (old_options.find(*i) != old_options.end())
warn_duplicate(*i);
else
old_options.insert(*i);
}
这是一个简单的O( m lg n )算法,其中 m = new_options.size()
和 n < / em> = old_options.size()
。
答案 2 :(得分:1)
这部分是larsmans的答案。有一个remove_copy_if
算法将他的for
循环封装到一个函数中。以下使用C ++ 0x lambda作为谓词。
void merge_options( set<string> &old_options, const set<string> &new_options )
{
remove_copy_if(
new_options.begin(),
new_options.end(),
inserter(old_options, old_options.end()),
[&](const string &s) {
return (old_options.count(s)) ? warn_duplicate(s), true : false;
}
);
}