【问题标题】:How to remove duplicates and keep only unique pointers in list? [duplicate]如何删除重复项并仅保留列表中的唯一指针? [复制]
【发布时间】:2012-08-20 13:21:15
【问题描述】:

可能重复:
How to make elements of vector unique? (remove non adjacent duplicates)
Remove duplicates from a list<int>

我有像

这样的指针列表
std::list<Person*> persons;

并且在填充过程中此列表中有重复项。如何删除重复项并仅保留列表中的唯一指针?

【问题讨论】:

  • 也许你选择了错误的数据结构?考虑切换到std::set
  • 是否要保留元素的相对顺序?

标签: c++ stl


【解决方案1】:

如果你可以改变元素的顺序,那么先用list::sort对列表进行排序,然后用list::unique删除重复的。

std::less<Person*> cmp;
persons.sort(cmp);
persons.unique(cmp);

另一方面,您可以使用std::set。它的元素是唯一的、有序的,如果集合中已经存在元素,insert 方法将失败。

请记住,插入单个元素的时间复杂度是对数,而将元素添加到列表的前面或后面是常数时间。另一方面,std::list::sortN*log(N)std::unique 是线性的。因此,如果您打算频繁执行这些重复删除,最好首先使用std::set。另请注意,在 C++11 中有 std::unordered_set,它具有元素唯一性和插入和删除的平均常数复杂度。

【讨论】:

  • 很遗憾sort 没有返回list&amp;...
  • 无论如何,一旦您进行O(N log N) 排序,插入时间并没有太大区别。
  • 如果您要在每个insert 之后调用sort()unique(),则set insert 会更快。可能快得多
  • @Dave 在每次插入后调用sort()unique() 会非常疯狂。但我会在这些方法的时间复杂度上添加几句话。
  • 如何对指针列表进行排序?您不能使用 来比较任意指针:stackoverflow.com/questions/4909766/…
【解决方案2】:

如果您不关心广告订单,请使用 set 而不是 list。它只能有独特的元素,它会自动进行其他人推荐的排序。

如果您确实关心插入顺序,请执行以下操作:

auto i = std::find(persons.begin(), persons.end(), pPerson);
if(i != persons.end())
    persons.erase(i);

persons.insert(pPerson);

(我没有编译那个)

【讨论】:

    【解决方案3】:

    根据他们指向的地址对列表进行排序。用一个简单的循环删除重复项。

    【讨论】:

      猜你喜欢
      • 2021-04-15
      • 1970-01-01
      • 1970-01-01
      • 2015-11-22
      • 1970-01-01
      • 2020-07-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多