You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++类方法中std::unordered_set调用set_intersection异常而std::set正常

问题原因分析
  • 核心原因是std::set_intersection算法对输入范围有强制前置要求:两个输入范围必须按照同一比较规则升序排序,否则会产生未定义行为。
  • std::set是有序关联容器,内部元素默认按照升序排列,完全满足std::set_intersection的输入要求,替换后运行结果自然正常。
  • std::unordered_set是哈希实现的无序关联容器,内部元素的遍历顺序由哈希规则、插入顺序、哈希冲突处理逻辑共同决定,没有固定的升序排列规则,传入std::set_intersection时不符合前置条件,结果不可预测。

为什么前两次测试能正常运行?

你最初手动初始化unordered_set时给定的初始化列表元素,碰巧在你的编译环境下遍历顺序是升序的,刚好满足set_intersection的要求,所以得到了正确结果。
而封装到Counter类之后,元素是按0→1→2的顺序逐个插入到unordered_set中,最终容器的遍历顺序不符合升序要求,set_intersection无法正确识别交集,所以返回了错误的0。

解决方案

  1. 保持现有逻辑不变,将所有std::unordered_set替换为std::set,利用std::set的有序性兼容std::set_intersection算法,你已经验证过该方案可行。
  2. 如果需要保留std::unordered_set的读写性能优势,不要使用std::set_intersection,改为手动遍历更小的集合查询交集:
size_t count(const std::pair<int,int>& pt) {
    const auto& x_set = _xs.at(pt.first);
    const auto& y_set = _ys.at(pt.second);
    size_t cnt = 0;
    // 优先遍历元素更少的集合,降低总查询次数
    if (x_set.size() <= y_set.size()) {
        for (size_t idx : x_set) {
            if (y_set.count(idx)) cnt++;
        }
    } else {
        for (size_t idx : y_set) {
            if (x_set.count(idx)) cnt++;
        }
    }
    return cnt;
}

内容的提问来源于stack exchange,提问作者janreggie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 09:09:04