【问题标题】:Create new sorted vector without duplicates创建没有重复的新排序向量
【发布时间】:2013-05-30 22:45:45
【问题描述】:

到目前为止我有这个功能:

std::vector<int> f(std::vector& v)
{
    std::vector<int> result;
    for(unsigned x = 0; x < v.size(); x++)
    {
        std::vector<int>::iterator location = std::find(result.begin(),result.end(),v[x]);
        if(location == result.end())
        {
            result.push_back(this->v[x]);
        }
    }
    std::sort(result.begin(),result.end());
    return result;
}

这个函数从 v 中返回一个无重复元素的排序向量。

有没有更简洁的写法?我读过关于 std::unique 的文章,但这涉及到编辑我不能做的向量。

【问题讨论】:

  • 你不能只取v的价值和std::sortstd::unique吗?

标签: c++ vector unique std


【解决方案1】:

由于您无论如何都在复制向量,所以只需复制,然后对结果进行排序和唯一化:

std::vector<int> f(std::vector<int> v) { 
    using std::begin;
    using std::end;

    std::sort(begin(v), end(v));
    v.erase(std::unique(begin(v), end(v)), end(v));
    return v;
}

【讨论】:

  • 不要忘记按值传递也可以打开动作。像这样的函数不需要传入左值更有意义。
  • @chris: 是的,在这种情况下特别有效,您需要接收复制/移动的项目,修改它,然后返回它。
  • 我当然认为按值获取向量并没有什么坏处。当然,在这种情况下,通过非常量引用传递是没有意义的。这个实现是 O(N) + O(n * log(N)),原来的似乎是 O(N!) + O(n * log(N))。
  • 我认为这两个函数都是正确的,如果 return.size()
【解决方案2】:

我读过关于 std::unique 的文章,但这涉及到编辑我无法做到的向量。

先复制一份!然后你可以像往常一样使用unique/erase。在 C++03 中你会写:

std::vector<int> f(const std::vector<int>& v)
//                 ^^^^^ you won't modify v, so make it obvious!
{
    std::vector<int> result(v); // copy the vector
    std::sort(result.begin(),result.end()); // sort it first so that std::unique can work
    std::erase(std::unique(result.begin(),result.end()), result.end()); // just keep the unique elements
    return result;
}

如果您使用 C++11,那么您可以利用移动语义和按值传递参数(将右值传递给函数时效率更高,并且对左值同样有效),这也允许你直接修改参数:

std::vector<int> f(std::vector<int> v)
//                 ^^^^^^^^^^^^^^^^ pass by value
{
    std::sort(v.begin(),v.end()); // sort it first so that std::unique can work
    std::erase(std::unique(v.begin(),v.end()), v.end()); // just keep the unique elements
    return v;
}

感谢@DavidBrown 和@chris,我倾向于忽略这个 C++11 习语,因为我还不习惯它。

【讨论】:

  • 由于您立即制作了向量的副本,因此您应该只按值传递向量。这在某些情况下允许certain optimizations
  • @DavidBrown:对,我还是经常忘记这个。有趣的是,我看到克里斯对杰瑞的回答发表了同样的评论。正在修复它,谢谢...
  • 更多的是允许将东西移动到参数中的情况。不需要将参数移动到result,直接使用它,因为它不是原始向量。
  • @chris:我的错。修复它再次...我真的必须习惯这个成语。 o_O
猜你喜欢
  • 2014-11-13
  • 2010-10-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-19
  • 2015-09-01
  • 1970-01-01
  • 2018-09-01
相关资源
最近更新 更多