【问题标题】:Remove duplicates in vector of structure c++删除结构 C++ 向量中的重复项
【发布时间】:2014-11-06 19:43:32
【问题描述】:

我有以下结构。我想将结构存储在向量中。其次,我想删除 (context) 上的重复值。我究竟做错了什么?


#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

//Structure
struct contextElement
{
  string context;
  float x;
};

int main()
{
  vector<contextElement> v1;
  v1.push_back({"1",1.0});
  v1.push_back({"2",2.0});
  v1.push_back({"1",1.0});
  v1.push_back({"1",1.0});
  //ERROR here
  auto comp = [] ( const contextElement& lhs, const contextElement& rhs ) {return lhs.context == rhs.context;};
  //Remove elements that have the same context
  v1.erase(std::unique(v1.begin(), v1.end(),comp));
  for(size_t i = 0; i < v1.size();i++)
  {
    cout << v1[i].context <<"  ";
  }
  cout << endl;
  return 0;
}

错误:

main.cpp|23|error: 没有匹配的调用函数 'std::vector::erase(__gnu_cxx::__normal_iterator >, std::vector::iterator, main()::__lambda0&)'|


可能的解决方案

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

//Structure
struct contextElement
{
  string context;
  float x;
};

int main()
{
  vector<contextElement> v1;
  v1.push_back({"1",1.0});
  v1.push_back({"2",2.0});
  v1.push_back({"1",1.0});
  v1.push_back({"1",1.0});
  //sort elements@HaniGoc: unique only removes consecutive duplicates. If you want to move all //duplicates, then either sort it first, or do something more complicated. –  Mike Seymour
  auto comp = [] ( const contextElement& lhs, const contextElement& rhs ) {return lhs.context < rhs.context;};
  sort(v1.begin(), v1.end(),comp);

  auto comp1 = [] ( const contextElement& lhs, const contextElement& rhs ) {return lhs.context == rhs.context;};
  auto last = std::unique(v1.begin(), v1.end(),comp1);
  v1.erase(last, v1.end());

  for(size_t i = 0; i < v1.size();i++)
  {
    cout << v1[i].context <<"  ";
  }
  return 0;
}

【问题讨论】:

  • 只需使用en.cppreference.com/w/cpp/algorithm/unique,具有相同的比较器。虽然为什么它小于而不是 == 让我感到困惑。
  • @MadScienceDreams 哦,你是对的。我还以为是排序呢
  • @MadScienceDreams "==" 即使只将 comp 添加到 Unique 也无济于事
  • 作为警告,此类问题的常见解决方案对于缺少 LH 和 RH 相等运算符重载的数据结构将是有问题的。基本上,它抱怨它无法将AB 进行比较。我在使用旧的 WinAPI stuct 时遇到了这个问题。

标签: c++ vector structure unique duplicate-removal


【解决方案1】:

vector::erase() 不带谓词。您对std::unique 的谓词应该检查是否相等。

【讨论】:

  • 是谓词 lambda 函数吗?
  • @HaniGoc:“谓词”是执行测试并返回 bool 的任何函数(或函数对象)。在这种情况下,它就是你的 lambda。
  • 不一定,它可以是提供满足所需测试的任何函数(或函子)(例如,unique,它是两个元素是否相等。)这可以通过函数也很简单,它不一定是 lambda,只是后者更方便恕我直言..
【解决方案2】:

不要将comp 传递给erase;它只需要一个迭代器范围。

v1.erase(std::unique(v1.begin(), v1.end(), comp), v1.end());

请注意,这只会删除 连续 个重复项。如果您想删除 所有 个重复项,并且不介意更改顺序,请先排序:

std::sort(v1.begin(), v1.end(),
    [] ( const contextElement& lhs, const contextElement& rhs ) {
        return lhs.context < rhs.context;
    });

【讨论】:

    【解决方案3】:
    auto comp = [] ( const contextElement& lhs, const contextElement& rhs ) {return lhs.context == rhs.context;};
    auto pred = []( const contextElement& lhs, const contextElement& rhs ) {return lhs.context < rhs.context;}
    std::sort(v.begin(),v.end(),pred);
    auto last = std::unique(v.begin(), v.end(),comp);
    v.erase(last, v.end());
    

    【讨论】:

    • 哦哦我应该对值进行排序吗?在申请独特之前??
    • @HaniGoc: unique 只删除 连续 个重复项。如果您想移动 所有 个重复项,请先对其进行排序,或者执行更复杂的操作。
    • 啊是的@MikeSeymour 我必须先对它们进行排序
    • @MikeSeymour 最后我将有 2 个值“1”和“2”
    • @HaniGoc 你也可以考虑使用std::set (O(nlgn)) 或std::unordered_set (O(n),但是对于小集合来说开销更高)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-13
    • 1970-01-01
    • 1970-01-01
    • 2016-04-01
    • 2020-04-29
    • 2016-08-12
    相关资源
    最近更新 更多