Продолжаем разговор про неупорядоченные типы данных и множества. Сегодня мы поговорим про операции над множествами. Если множества вам знакомы из логики или математики, возможно, вы слышали эти слова: объединение, пересечение или разность множеств. Если вы не слышали — ничего страшного, сейчас будем вместе вспоминать и разбираться. Например, вам нужно решить такую задачу: есть три электива, и есть списки студентов, которые выбрали каждый из этих курсов. Возможно, есть студенты, которые выбрали все три электива, есть те, кто выбрал только один, какие-то выбрали два из этих трех. Вы хотите получить список студентов, где каждый студент будет встречаться один раз, то есть список студентов, которые выбрали хотя бы один из этих трех курсов. Такая операция будет называться операцией объединения. Мы получили множество уникальных студентов, которые выбрали каждый из курсов, и объединили их — у нас получилось множество уникальных студентов, которые выбрали хотя бы один из этих курсов. Если студент выбрал все три — в это множество он попал один раз. Или предположим, мы решаем такую задачу: мы хотим назначить время консультации, и дали студентам на выбор три времени: в 15:00, в 16:00 и в 17:00. Каждый студент пишет, когда ему удобно, и, по сути, мы выполняем операцию — пересечение множеств, ведь нам надо понять, какой час попал в пересечение, какой час удобен всем студентам. Это могут быть все три, тогда выберем тот, который удобнее нам как преподавателю. Или предположим, мы хотим приготовить торт. У нас есть рецепт и список продуктов, и мы идем смотреть: а что же есть у нас дома из этого? Предположим, нам не хватает молока и яиц, их надо купить. Получается, мы получили разность двух множеств: продукты, которые нам нужны, и продукты, которые есть у нас дома. То, чего нет — разность множеств, пойдем, докупим их. Давайте теперь смотреть, как это выразить формально. В нашем примере будем использовать диаграммы Эйлера — Венна, и будем работать с такими множествами: предположим, есть список животных, которые нравятся вам — шиншилла, рыбка, кошка и ужик (зеленый круг), и список животных, которые нравятся вашему другу — питон, хамелеон, собака, кошка и ужик. Это два множества, на них будем отрабатывать наши операции. Первая операция — это операция объединения. Операция объединения всех множеств (это пример со студентами, которые выбирали разные курсы) — это все уникальные элементы, которые входят в наше множество. Как мы видим, кошку и ужика хотим и мы, и друг, поэтому кошка и ужик в объединение попадет один раз, а так это и шиншилла, и рыбка, и питон, то есть множество всех животных, которые нам в принципе нравятся (нравятся хотя бы одному из нас). Следующая операция — пересечение. Вот это как раз только кошка и ужик. В изначальной диаграмме это область, которая попала на пересечение двух кругов: множество животных, которые нравятся нам, и множество животных, которые нравятся нашему другу — это животные, которые нравятся нам обоим одновременно. Например, если бы мы планировали, кого завести, выбирали бы явно из них. Следующая операция — это разность. Мы с вами обсудили, что разность — это когда мы из одного множества вычитаем другое и смотрим, какие элементы остались. Соответственно, разность может в нашем случае быть: множество A минус множество B — множество животных, которые нравятся мне, минус множество животных, которые нравятся моему другу. По сути, это животные, которые не попадают в пересечение с животными моего друга — животные, которые нравятся только мне. Если мы поменяем слагаемые местами (в данном случае множества), то мы найдем, наоборот, разность: множество B минус множество A, то есть это животные, которые нравятся только другу, но не нравятся нам. Иногда у нас есть такая задача, когда нам нужно найти симметрическую разность, то есть, по сути, это разность мои животные минус животные друга плюс разность животные друга минус животные, которые нравятся мне. Например, в данном случае животные, которые не нравятся кому-то одному из нас, то есть шиншилла и рыбка не нравятся моему другу, а питон, хамелеон и собака не нравятся мне — в целом, это животные, которые кому-то из нас чем-то не угодили, хотя бы одному. И у нас есть такая операция, поэтому мы тоже сможем ее найти. Если подумать, можно представить симметрическую разность не только как сумму двух разностей, но еще как объединение, ведь посмотрите — это действительно все животные, которые нравятся хотя бы одному из нас, и здесь не хватает одного кусочка — пересечения наших множеств. То есть если из объединения мы вычтем пересечение, получим как раз симметрическую разность. А теперь давайте как раз решим задачу. Будем работать с этими множествами и посмотрим, какое животное мы бы завели, если бы нам с другом пришлось бы выбрать вместе.