【问题标题】:Why does std::set_difference not remove duplicates?为什么 std::set_difference 不删除重复项?
【发布时间】:2020-12-25 02:42:38
【问题描述】:

cppreference 声明std::set_difference

从排序范围 [first1, last1) 中复制未在排序范围内找到的元素 range [first2, last2) 到从 d_first 开始的范围。

话虽如此,我希望以下 MWE 输出 2 4,因为只有 2 和 4 不在第二组中。

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

int main() {
    std::vector<int> A{1, 1, 2, 2, 2, 3, 3, 4};
    std::set<int> B{1, 3};
    std::set<int> difference;
    std::set_difference(
        A.cbegin(), 
        A.cend(), 
        B.cbegin(),
        B.cend(), 
        std::inserter(difference, difference.end())
    );

    std::for_each(difference.cbegin(), difference.cend(), [](int n) {
        std::cout << n << " ";
    });
    std::cout << std::endl;
}

但是,这似乎输出了1 2 3 4,我不完全确定为什么。如果我将A 更改为仅包含1 2 3 4,它会达到我的预期效果有人可以帮助我理解这一点吗?

【问题讨论】:

  • 你引用的那一段后面的段落说:等效元素被单独处理,也就是说,如果在[first1, last1)[first2, last2)中找到m次和n次的某个元素,它将被复制到 d_first 精确到 std::max(m-n, 0) 次。
  • 废话。我不敢相信我错过了。谢谢你。如果您将此作为答案发布,我会接受。
  • @ollien 老实说,如果您期望 C++ 标准库直观且易于使用,那么您使用的是错误的编程语言。它是为库编写者构建的(似乎也很少有人使 他们的 库变得直观且易于使用)。我对各种标准库功能和非功能有一个长达一英里的反对列表,但我找不到任何以用户为中心的解释。
  • @Tumbleweed53 -- C++ 标准库提供工具,而不是最终解决方案。这些工具可帮助您构建所需的东西,而不是提供一组专门的东西,如果您尝试做一些稍微不同的事情,则必须与之抗争。
  • @PeteBecker 够公平的。

标签: c++ stl


【解决方案1】:

我不确定是否有充分的理由必须将其定义为以这种方式工作,但这绝对是它的定义方式。该标准特别要求这种行为。这是 N4835 的措辞(§[set.difference]/6):

备注:若[first1,last1)包含m个相互等价的元素,[first2,last2)包含n个与其等价的元素,则[first1, last1) 按顺序复制到输出范围内。

【讨论】:

  • 我会说逻辑是保留union(A, B) == difference(A, B) + difference(B, A) + Intersection(A, B)。并且作为模数,有几个选项。
猜你喜欢
  • 2019-07-27
  • 1970-01-01
  • 2020-01-04
  • 1970-01-01
  • 1970-01-01
  • 2017-09-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多