{ }codelper
setssorting listsP0099

Union, intersection, difference

The first line gives n, the second line n integers (group A), the third line m, and the fourth line m integers (group B).
The same number may appear more than once in a group, but as a set it counts once.
Print three lines. 1.
The union of A and B (numbers in at least one of them) 2.
The intersection of A and B (numbers in both) 3.
The difference A minus B (numbers in A but not in B) On each line print each number once, smallest first, separated by single spaces.
If there are no such numbers, print a single "-".

Input
1 ≤ n, m ≤ 5,000, -2,000,000,000 ≤ each integer ≤ 2,000,000,000
Output
three lines (union, intersection, difference)
Example 1 · stdin
7
10 9 2 100 -1 -20 3
5
9 100 -20 7 7
stdout
-20 -1 2 3 7 9 10 100
-20 9 100
-1 2 3 10
Example 2 · stdin
3
5 5 5
1
5
stdout
5
5
-
main.py
Input (stdin)

When you run, these lines are fed to input()/stdin in order (the program doesn't stop to ask).

$ Ready

Open this on a computer to write and run code. On mobile you can read the problem and the solutions.

In other languagesShow solutions by language · 8 languages

Set operations go by different names.
Python has the operators a | b, a & b, a - b; Java has addAll, retainAll, removeAll; C# has UnionWith, IntersectWith, ExceptWith.
The Java and C# methods change the set itself, so call them on a copy.
C++'s std::set_union, set_intersection and set_difference take sorted ranges, which fits std::set (always sorted).
JS/TS Set lacked set operations for a long time (union and friends arrived only recently), so filter(x => b.has(x)) is common.
Watch the order too.
A Python set does not iterate in size order, so you need sorted, and JS/TS sort() without a compare function sorts as text, putting 10 before 9; write sort((x, y) => x - y).
Java TreeSet and C# SortedSet are always in size order.
C has no set, so sort both, remove repeats, and walk both from the front together (a merge).
If the qsort compare function returns a - b, subtracting values around ±2e9 overflows int (about ±2.1e9) and the order breaks; write (a > b) - (a < b).
Another common mistake is building the difference as a list ([x for x in a if x not in b]), which keeps repeated values.
Craykon uses the keys of a Dict() as a set, asks with Contains, then Sort()s the Keys and writes them with Join(" ").

Pythonmain.py · 14 lines
input()a = set(map(int, input().split()))input()b = set(map(int, input().split()))  def show(s):    # 집합에는 차례가 없으니 출력 전에 크기 순으로 늘어놓는다    return " ".join(map(str, sorted(s))) if s else "-"  print(show(a | b))print(show(a & b))print(show(a - b))
JavaScriptmain.js · 9 lines
const lines = require("fs").readFileSync(0, "utf8").split("\n");const a = new Set(lines[1].trim().split(/\s+/).map(Number));const b = new Set(lines[3].trim().split(/\s+/).map(Number));// sort()만 쓰면 글자 순(10이 9보다 앞)이라 비교 함수를 준다const show = (s) => (s.size ? [...s].sort((x, y) => x - y).join(" ") : "-");const union = new Set([...a, ...b]);const inter = new Set([...a].filter((x) => b.has(x)));const diff = new Set([...a].filter((x) => !b.has(x)));console.log([show(union), show(inter), show(diff)].join("\n"));
TypeScriptmain.ts · 10 lines
import { readFileSync } from "node:fs";const lines: string[] = readFileSync(0, "utf8").split("\n");const a = new Set<number>(lines[1].trim().split(/\s+/).map(Number));const b = new Set<number>(lines[3].trim().split(/\s+/).map(Number));// sort()만 쓰면 글자 순(10이 9보다 앞)이라 비교 함수를 준다const show = (s: Set<number>): string => (s.size ? [...s].sort((x, y) => x - y).join(" ") : "-");const union = new Set<number>([...a, ...b]);const inter = new Set<number>([...a].filter((x) => b.has(x)));const diff = new Set<number>([...a].filter((x) => !b.has(x)));console.log([show(union), show(inter), show(diff)].join("\n"));
JavaMain.java · 35 lines
import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.util.TreeSet; public class Main {    static TreeSet<Integer> readSet(BufferedReader in) throws IOException {        in.readLine();        TreeSet<Integer> s = new TreeSet<>();        for (String t : in.readLine().trim().split("\\s+")) s.add(Integer.parseInt(t));        return s;    }     static String show(TreeSet<Integer> s) {        if (s.isEmpty()) return "-";        StringBuilder sb = new StringBuilder();        for (int x : s) sb.append(sb.length() > 0 ? " " : "").append(x);        return sb.toString();    }     public static void main(String[] args) throws IOException {        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));        // TreeSet은 늘 크기 순으로 돈다. addAll·retainAll·removeAll은 원래 집합을 바꾸니 복사해서 쓴다        TreeSet<Integer> a = readSet(in), b = readSet(in);        TreeSet<Integer> union = new TreeSet<>(a);        union.addAll(b);        TreeSet<Integer> inter = new TreeSet<>(a);        inter.retainAll(b);        TreeSet<Integer> diff = new TreeSet<>(a);        diff.removeAll(b);        System.out.println(show(union));        System.out.println(show(inter));        System.out.println(show(diff));    }}
C#Main.cs · 30 lines
using System;using System.Collections.Generic;using System.Linq; class Program{    static SortedSet<int> ReadSet()    {        Console.ReadLine();        return new SortedSet<int>(Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries).Select(int.Parse));    }     static string Show(SortedSet<int> s) => s.Count == 0 ? "-" : string.Join(" ", s);     static void Main()    {        // SortedSet은 늘 크기 순으로 돈다. UnionWith 등은 원래 집합을 바꾸니 복사해서 쓴다        var a = ReadSet();        var b = ReadSet();        var union = new SortedSet<int>(a);        union.UnionWith(b);        var inter = new SortedSet<int>(a);        inter.IntersectWith(b);        var diff = new SortedSet<int>(a);        diff.ExceptWith(b);        Console.WriteLine(Show(union));        Console.WriteLine(Show(inter));        Console.WriteLine(Show(diff));    }}
C++main.cpp · 34 lines
#include <algorithm>#include <iostream>#include <iterator>#include <set>#include <vector> std::set<int> read_set() {    int n, x;    std::cin >> n;    std::set<int> s;    for (int i = 0; i < n; i++) {        std::cin >> x;        s.insert(x);    }    return s;} void show(const std::vector<int>& v) {    if (v.empty()) std::cout << "-";    for (std::size_t i = 0; i < v.size(); i++) std::cout << (i ? " " : "") << v[i];    std::cout << '\n';} int main() {    // std::set은 크기 순이라 set_union 등에 바로 넘길 수 있다(정렬된 범위가 필요하다)    std::set<int> a = read_set(), b = read_set();    std::vector<int> u, in, d;    std::set_union(a.begin(), a.end(), b.begin(), b.end(), std::back_inserter(u));    std::set_intersection(a.begin(), a.end(), b.begin(), b.end(), std::back_inserter(in));    std::set_difference(a.begin(), a.end(), b.begin(), b.end(), std::back_inserter(d));    show(u);    show(in);    show(d);}
Cmain.c · 50 lines
#include <stdio.h>#include <stdlib.h> // a - b 를 돌려주면 ±20억끼리 빼서 int가 넘친다 — 크기만 비교한다static int cmp(const void *pa, const void *pb) {    int a = *(const int *)pa, b = *(const int *)pb;    return (a > b) - (a < b);} // 읽어서 정렬한 뒤 겹친 값을 지운다. 남은 개수를 돌려준다static int read_set(int *s) {    int n;    scanf("%d", &n);    for (int i = 0; i < n; i++) scanf("%d", &s[i]);    qsort(s, n, sizeof s[0], cmp);    int k = 0;    for (int i = 0; i < n; i++)        if (k == 0 || s[k - 1] != s[i]) s[k++] = s[i];    return k;} static void show(const int *s, int n) {    if (n == 0) printf("-");    for (int i = 0; i < n; i++) printf(i ? " %d" : "%d", s[i]);    printf("\n");} int main(void) {    static int a[5000], b[5000], u[10000], in[5000], d[5000];    int n = read_set(a), m = read_set(b);    int nu = 0, ni = 0, nd = 0, i = 0, j = 0;    // 정렬된 두 목록을 앞에서부터 함께 훑는다(병합)    while (i < n || j < m) {        if (j == m || (i < n && a[i] < b[j])) {            u[nu++] = a[i];            d[nd++] = a[i++];        } else if (i == n || b[j] < a[i]) {            u[nu++] = b[j++];        } else {            u[nu++] = a[i];            in[ni++] = a[i];            i++;            j++;        }    }    show(u, nu);    show(in, ni);    show(d, nd);    return 0;}
Craykonmain.cray · 47 lines
// 사전의 열쇠를 집합처럼 쓴다(값은 아무거나)집합읽기(){    Console.ReadLine();    s = Dict();    foreach (x in Console.ReadNumbers())    {        s[x] = true;    }    return s;} 보이기(s){    if (s.Count == 0)    {        return "-";    }    keys = s.Keys;    keys.Sort();    return keys.Join(" ");} a = 집합읽기();b = 집합읽기();합 = Dict();교 = Dict();차 = Dict();foreach (x in a.Keys){    합[x] = true;    if (b.Contains(x))    {        교[x] = true;    }    else    {        차[x] = true;    }}foreach (x in b.Keys){    합[x] = true;}Console.WriteLine(보이기(합));Console.WriteLine(보이기(교));Console.WriteLine(보이기(차));