减去包含重复元素的向量

Subtract vectors, that contain duplicated elements

本文关键字:向量 元素 包含重      更新时间:2023-10-16

有什么优雅的方法可以减去包含重复元素的std::vector s吗?


例:

v1 = { 3, 1, 2, 1, 2, 2 }
v2 = { 2, 4, 3, 3, 3 }
result1 = ??( v1, v2 )
result2 = ??( v2, v1 )

我希望结果是:

result1 = { 1, 1 }
result2 = { 4 }

我目前(而且非常慢)的解决方案:

1) sort v1 and v2
2) use std::unique_copy to v1_uniq, v2_uniq
3) intersect the new vectors with std::set_intersection
4) iterate over v1 and v2 and remove all elements, that are in the intersection 3)

我的另一个想法是:

1) sort v1 and v2
2) iterate over v1 and v2 and remove duplicates in parallel 

但这有点容易出错,对我来说看起来并不优雅。

还有其他想法吗?

您可以将 std::copy_if 与一元谓词一起使用,用于检查元素是否在第二个向量中。或者,如果您没有 C++11 支持,请使用 std::remove_copy_if 并适当更改谓词的逻辑。

对于一元谓词:

struct Foo {
  Foo(const std::vector& v) : v_(v) {}
  bool operator() (int i) const {
    // return true if i is in v_
  }
  const std::vector<int>& v_;
};

可以像这样实例化:

Foo f(v2);

您可以修改函子以保留参考向量的排序版本,并具有唯一条目以允许进行二叉搜索,但总体思路是相同的。

我有一个相当简单的算法,其复杂度为 O(n²)。但是,使用排序(O(n log n))可以更快。在这里:

substract s from v
    for all elements of v
        for all elements of s
            if element i-th of v == element j-th of s
                then remove it from v and break the loop on s

对于其他结构,也许它可以更快。例如,如果元素是共享的,则可以分离与 s 共享的所有 v 元素,复杂度为 O(n)。