赋值vs std :: swap并合并并在单独的对象中保留重复项

时间:2011-03-06 16:07:25

标签: c++ algorithm merge set

说我有两个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;
}
  1. 使用

    更好吗?
    std::swap( merged_options, old_options );
    

    或我的作业?

  2. 是否有更好的方法来过滤重复项并返回合并的set,而不是连续调用std::set_intersectionstd::set_union以检测欺骗并合并set s ?我知道它比一次遍历慢,并且一次做两次,但这些设置很小(性能并不重要),我相信标准比我更信任我自己。

3 个答案:

答案 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;
        }
    );
}