赋值与 std::swap 以及合并并将重复项保留在单独的对象中

发布于 2024-10-20 07:09:39 字数 819 浏览 5 评论 0原文

假设我有两个 std::set。第一个 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. 是否有比连续调用 std::set_intersectionstd::set_union 更好的方法来过滤重复项并返回合并的 set检测重复项并合并集合?我知道它比一次遍历并同时执行两者要慢,但这些集合很小(性能并不重要),而且我对标准的信任超过对自己的信任。

Say I have two std::set<std::string>s. The first one, old_options, needs to be merged with additional options, contained in new_options. I can't just use std::merge (well, I do, but not only that) because I also check for doubles and warn the user about this accordingly. To this effect, I have

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. Is it better to use

    std::swap( merged_options, old_options );
    

    or the assignment I have?

  2. Is there a better way to filter duplicates and return the merged set than consecutive calls to std::set_intersection and std::set_union to detect dupes and merge the sets? I know it's slower than one traversal and doing both at once, but these sets are small (performance is not critical) and I trust the Standard more than I trust myself.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

抚笙 2024-10-27 07:09:39

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 = old_options.size()

What's wrong with

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

This is a simple O(m lg n) algorithm, where m = new_options.size() and n = old_options.size().

儭儭莪哋寶赑 2024-10-27 07:09:39

鉴于(正如您所说)性能在这里并不重要,我将使用赋值和两遍算法。更简单、更容易理解;只有当你真的需要它所获得的东西时,才值得使用像交换这样的“技巧”。

编写自己的算法并不是一件坏事,但同样,除非您真正使用它提供的好处,否则我不会打扰。

Given (as you've stated) that performance isn't critical here, I'd use the assignment and the two-pass algorithm. It's simpler and easier to understand; it's only worth using a "trick" like swap if you really need what it gains.

Writing your own algorithm wouldn't be such a bad thing, but again, unless you have a real use for the benefit it provides, I wouldn't bother.

舞袖。长 2024-10-27 07:09:39

这在一定程度上是对拉斯曼的回答。有一个 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;
        }
    );
}

This is in part an answer to larsmans. There is a remove_copy_if algorithm that encapsulates his for loop into a single function. The following uses a C++0x lambda for the predicate.

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;
        }
    );
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文