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

C++中如何优雅实现三集合(A∩B)∪(B∩C)∪(A∩C)及单行求交集

Great questions! Let's break down solutions for both of your requests:

1. Implementing (A ∩ B) ∪ (B ∩ C) ∪ (A ∩ C) without 4 extra sets

Your original approach uses 4 intermediate sets, but we can cut that down to just one result set by leveraging the fact that std::set automatically handles duplicate elements. Instead of storing each intersection in a separate set, we can directly insert the results of each intersection into the final result set—since duplicates will be ignored automatically.

Here's the optimized code:

#include <set>
#include <algorithm>
using namespace std;

int main() {
    set<int> set1 = {1, 2};
    set<int> set2 = {2, 3};
    set<int> set3 = {1, 4};

    set<int> result;
    // Insert elements from A∩B directly into result
    set_intersection(set1.begin(), set1.end(),
                     set2.begin(), set2.end(),
                     inserter(result, result.begin()));
    // Insert elements from B∩C (set auto-deduplicates duplicates)
    set_intersection(set2.begin(), set2.end(),
                     set3.begin(), set3.end(),
                     inserter(result, result.begin()));
    // Insert elements from A∩C
    set_intersection(set1.begin(), set1.end(),
                     set3.begin(), set3.end(),
                     inserter(result, result.begin()));

    // Result is {1, 2} which matches the expected union of intersections
    return 0;
}

This eliminates the need for res1, res2, and res3 entirely—only one extra set (result) is required, which is way better than the original 4.

2. Single-line (or clean) implementation for three-set intersection

For the intersection of three sets (A ∩ B ∩ C), we can write concise code either by nesting set_intersection calls or using modern C++ features. Here are a few options:

Option 1: Nested set_intersection (C++11+)

You can chain the intersection operations using a temporary set for the first intermediate result. To make it "single-line" in practice, wrap it in a template function for reusability:

template <typename T>
set<T> three_set_intersection(const set<T>& a, const set<T>& b, const set<T>& c) {
    set<T> ab_intersect;
    set_intersection(a.begin(), a.end(), b.begin(), b.end(), inserter(ab_intersect, ab_intersect.begin()));
    set<T> abc_intersect;
    set_intersection(ab_intersect.begin(), ab_intersect.end(), c.begin(), c.end(), inserter(abc_intersect, abc_intersect.begin()));
    return abc_intersect;
}

// Call it in one line:
set<int> three_intersect = three_set_intersection(set1, set2, set3);

Option 2: C++20 Ranges & contains (cleaner, more efficient)

If you're using C++20 or later, you can use ranges and std::set::contains (a faster alternative to count()) to filter elements that exist in all three sets:

#include <ranges>
#include <set>

// One-line conversion to set:
set<int> three_intersect(set1 | std::views::filter([&](int x) { 
    return set2.contains(x) && set3.contains(x); 
}));

This is more readable than nested algorithm calls and avoids intermediate sets entirely (the range view is evaluated lazily).

Bonus: Even more elegant approach for your original union-of-intersections expression

For (A ∩ B) ∪ (B ∩ C) ∪ (A ∩ C), we can rephrase the logic: it's all elements that appear in at least two of the three sets. Using C++20 ranges, this becomes extremely clean:

set<int> result(
    std::views::concat(set1, set2, set3)
    | std::views::filter([&](int x) {
        int count = 0;
        count += set1.contains(x);
        count += set2.contains(x);
        count += set3.contains(x);
        return count >= 2;
    })
    | std::views::unique
);

This avoids all set_intersection and set_union calls entirely, replacing them with a straightforward filter based on element presence.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:13:34