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

如何用C++ ranges::set_intersection()实现类似SQL Join的关联结果?

实现基于C++ Ranges的SQL风格Inner Join(配对匹配元素)

你的需求是通过ranges::set_intersection实现类似SQL Inner Join的功能,得到匹配id的Item1和Item2配对集合。但原生的ranges::set_intersection仅能输出第一个输入序列的交集元素(或投影后的id),无法直接生成跨序列的元素配对。以下是两种可行的实现方案:

方案1:双指针法(高效,模拟set_intersection底层逻辑)

因为你的两个序列已经按id升序排列,我们可以手动实现双指针遍历,直接收集匹配的元素配对,时间复杂度为O(n+m),和set_intersection一致:

#include <string>
#include <vector>
#include <utility>
using namespace std;

struct Item1{int id; int data;};
vector<Item1> v1 = {{.id=1,.data=42},{.id=2,.data=69}};
struct Item2{int id; string data;};
vector<Item2> v2 = {{.id=1, .data="banana"},{.id=3,.data="coconut"}};

// 定义配对类型,也可以用自定义结构体
using JoinedPair = pair<Item1, Item2>;
vector<JoinedPair> joined_result;

auto it1 = v1.begin();
auto it2 = v2.begin();

while (it1 != v1.end() && it2 != v2.end()) {
    if (it1->id < it2->id) {
        ++it1; // v1当前id更小,移动指针
    } else if (it2->id < it1->id) {
        ++it2; // v2当前id更小,移动指针
    } else {
        // id匹配,生成配对并加入结果
        joined_result.emplace_back(*it1, *it2);
        ++it1;
        ++it2;
    }
}

// 验证输出
for (const auto& pair : joined_result) {
    printf("匹配结果:id=%d, Item1.data=%d, Item2.data=%s\n",
           pair.first.id, pair.first.data, pair.second.data.c_str());
}

方案2:结合Ranges视图与二分查找(保持Ranges风格)

如果你希望保留Ranges的使用方式,可以先通过set_intersection获取交集id,再利用序列已排序的特性,用二分查找快速定位对应元素生成配对:

#include <string>
#include <vector>
#include <algorithm>
#include <ranges>
#include <utility>
using namespace std;
using namespace std::views;

struct Item1{int id; int data;};
vector<Item1> v1 = {{.id=1,.data=42},{.id=2,.data=69}};
struct Item2{int id; string data;};
vector<Item2> v2 = {{.id=1, .data="banana"},{.id=3,.data="coconut"}};

using JoinedPair = pair<Item1, Item2>;
vector<JoinedPair> joined_result;

// 获取两个序列id的交集视图
auto common_ids = v1 | transform(&Item1::id) | set_intersection(v2 | transform(&Item2::id));

// 遍历交集id,通过二分查找匹配元素并生成配对
for (int id : common_ids) {
    auto item1_iter = ranges::lower_bound(v1, id, {}, &Item1::id);
    auto item2_iter = ranges::lower_bound(v2, id, {}, &Item2::id);
    joined_result.emplace_back(*item1_iter, *item2_iter);
}

// 验证输出
for (const auto& pair : joined_result) {
    printf("匹配结果:id=%d, Item1.data=%d, Item2.data=%s\n",
           pair.first.id, pair.first.data, pair.second.data.c_str());
}

两种方案最终都会得到你期望的配对集合:[{Item1(id=1, data=42), Item2(id=1, data="banana")}]。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 16:15:31