Множество Set

Последнее обновление: 31.01.2024

Тип Set или множество в языке F# представляет набор данных, основанный на бинарных деревьях, который хранит только уникальные элементы.

Создание множества

Для определения множества применяется оператор set, которому передается последовательность значений:

let people = set ["Tom"; "Bob"; "Sam"]
printfn $"People: {people}"   // People: set [Tom, Bob, Sam]

В данном случае в качестве последовательности применяется список из трех строк, соответственно множество будет содержать три строки. С помощью функции printfn можно вывести множество на консоль.

Для создания множества в объектно-ориентированном стиле можно применять конструктор типа Set, в который передается последовательность элементов:

let employees = ["Tom"; "Bob"; "Sam"]
let people = Set(employees)
printfn $"People: {people}"   // People: set ["Tom"; "Bob"; "Sam"]

Здесь аналогично создается множество people а основе списка employees.

Стоит отметить, что тип Set является обобщенным, поэтому конкретные множества типизируются типом его элементов. Так, в примере выше в реальности создается объект Set<'string>, и мы могли бы явным образом указать тип:

let people: Set<'string> = set ["Tom"; "Bob"; "Sam"]
printfn $"People: {people}"   // People: set ["Tom"; "Bob"; "Sam"]

Для создания множество также модуль Set предоставляет ряд функций. Так, функция Set.empty создает пустое множество:

let people = Set.empty

Также есть ряд функций для создания множества из конкретных последовательностей:

  • Set.ofArray: создает множество из массива

  • Set.ofList: создает множество из списка

  • Set.ofSeq: создает множество из последовательности

let set1 = Set.ofArray [|"Tom"; "Bob"; "Sam"|]
printfn $"{set1}"   // set [Tom; Bob; Sam]

let set2 = Set.ofList ["Tom"; "Bob"; "Sam"]
printfn $"{set2}"   // set [Bob; Sam; Tom]

let set3 = Set.ofSeq["Tom", "Bob", "Sam"]
printfn $"{set3}"   // set [(Tom, Bob, Sam)]

Причем важно понимать, что множество - это набор уникальных значений, дубликатов в нем быть не может. Например:

let usersList =  ["Tom"; "Bob"; "Sam"; "Bob"; "Tom"; "Sam"]         // список
let usersSet = set usersList                                        // множество
printfn $"{usersList}"   // ["Tom"; "Bob"; "Sam"; "Bob"; "Tom"; "Sam"] 
printfn $"{usersSet}"   // set [Bob; Sam; Tom]

В данном случае множество создается на основе списка с дублями. Однако, как мы можем увидеть, созданное множество не содержит дублей, а только уникальные элементы. Подобная техника нередко применяется для отсеивания дублей в различных языказ программирования.

Другой важный момент - упорядочивание элементов. Если вы обратите внимание на консольный вывод множества, то увидите, что элементы в нем упорядочены по возрастанию, хотя в изначальном списке они были расположены в другом порядке:

set [Bob; Sam; Tom]

Методы Set

Тип Set предоставляет ряд методов для управления множествами:

  • Add: возвращает копию множества, в которую добавлен новый элемент.

  • Contains: возвращает true, если множество содержит определенный элемент

  • Count: возвращает количество элементов множества

  • IsEmpty: возвращает true, если множество пустое.

  • IsProperSubsetOf: возвращает true, если второе множество (из параметра) содержит первое множество, и при этом второе множество содержит как минимум один элемент, которого нет в первом

  • IsProperSupersetOf: возвращает true, если первое множество содержит второе множество (из параметра), и при этом первое множество содержит как минимум один элемент, которого нет в втором

  • IsSubsetOf: возвращает true, если второе множество (из параметра) содержит первое множество

  • IsSupersetOf: возвращает true, если первое множество содержит второе множество (из параметра)

  • MaximumElement: возвращает наибольший элемент множества.

  • MinimumElement: возвращает наименьший элемент.

  • Remove: возвращает копию множества, из которого удален определенный элемент.

Перебор множества

Для перебора множества можно использовать циклические конструкции, например, цикл for-in:

let people = set ["Tom"; "Bob"; "Sam"]
for person in people do printfn "%s" person

Кроме того, модуль Set предоставляет функцию Set.iter:

Set.iter action set

Ее первый параметр - функция-действие, в которую передается каждый элемент множества, а второй параметр - само множество. Применение:

let people = set ["Tom"; "Bob"; "Sam"]
Set.iter (fun p -> printfn "%s" p) people

Размер множества

Для получения размера множества можно использовать либо функцию Set.count, в которую передается множество, либо свойство Count типа Set:

let people = set ["Tom"; "Bob"; "Sam"]
printfn "Count: %d" (Set.count people)
printfn "Count: %d" (people.Count)

С помощью функции Set.isEmpty и свойства IsEmpty типа Set можно проверить множество на наличие элементов - если множество пустое, они возвращают true:

let people = set ["Tom"; "Bob"; "Sam"]
printfn "people is empty?  %b" (Set.isEmpty people)
printfn "people is empty?  %b" (people.IsEmpty)

let students = Set.empty
printfn "students is empty?  %b" (Set.isEmpty students)
printfn "students is empty?  %b" (students.IsEmpty)

Проверка наличия элемента

Для проверки наличия элемента во множестве применяется функция Set.contains

Set.contains element set

Применение:

let people = set ["Tom"; "Bob"; "Sam"]

printfn "Sam in people? %b" (Set.contains "Sam" people)         // true
printfn "Alex in people? %b" (Set.contains "Alex" people)       // false

Также в качестве альтернативы можно использовать метод Contains() объекта Set:

let people = set ["Tom"; "Bob"; "Sam"]

printfn "Sam in people? %b" (people.Contains("Sam"))         // true
printfn "Alex in people? %b" (people.Contains("Alex"))       // false

Для проверки элементов множества модуль Set предоставляет еще две функции:

  • Set.exists predicate set: возвращает true, если хотя бы один элемент множества удовлетворяет условию

  • Set.forall predicate set: возвращает true, если хотя бы один элемент множества удовлетворяет условию

Обе функции в качестве первого параметра принимают функцию-условие, которая получает каждый элемент множества и возвращает true или false в зависимости от того, соответствует ли элемент условию. Второй параметр - само множество. Применение:

let numbers = set [1; 2; 3; 4; 5; 6]

// если ли элементы больше 3
printfn "%b" (Set.exists (fun n -> n > 3) numbers)  // true
// если ли элементы больше 9
printfn "%b" (Set.exists (fun n -> n > 9) numbers)  // false


// все ли элементы больше 3
printfn "%b" (Set.forall (fun n -> n > 3) numbers)  // false
// все ли элементы больше 0
printfn "%b" (Set.forall (fun n -> n > 0) numbers)  // true

Добавление во множество

Для добавления новых элементов применяется функция Set.add:

Set.add value set

Функции передается добавляемое значение и множество. Но стоит учитывать, что множество - это неизменяемая коллекция, и в реальности будет создаваться новое множество, которое будет включать элементы оригинального множества и добавляемый элемент:

let people_old = set ["Tom"; "Bob"; "Sam"]
let people_new = Set.add "Alice" people_old     // Добавляем в множество строку "Alice"

printfn $"Original set: {people_old}"       // set ["Bob"; "Sam"; "Tom"]
printfn $"New set: {people_new}"           // set ["Alice";"Bob"; "Sam"; "Tom"]

В качестве альтернативы можно использовать метод Add() объекта Set:

let people_old = set ["Tom"; "Bob"; "Sam"]
let people_new = people_old.Add("Alice")

printfn $"New set: {people_new}"           // set ["Alice";"Bob"; "Sam"; "Tom"]

Удаление элементов

Для удаления элемента из множества модуль Set предоставляет функцию Set.remove, в которую передается удаляемый элемент и множество:

Set.remove value set

И опять же, как и в случае с добавлением, эта функция не изменяет начальное множество, а возвращает новое, которое не содержит удаляемый элемент. Например:

let people_old = set ["Tom"; "Bob"; "Sam"]
let people_new = Set.remove "Sam" people_old  // удаляем строку "Sam"

printfn $"Original set: {people_old}"       // set ["Bob"; "Sam"; "Tom"]
printfn $"New set: {people_new}"           // set ["Bob"; "Tom"]

Также для удаления можно использовать метод Remove() объекта Set:

let people_old = set ["Tom"; "Bob"; "Sam"]
let people_new = people_old.Remove("Sam")

printfn $"New set: {people_new}"           // set ["Bob"; "Tom"]

Фильтрация и преобразование множества

Для фильтрации множества применяется функция :

Set.filter predicate set

Первый параметр функции - функция, которая проверяет каждый элемент на соответствие условию и при соответствии возвращает true, а второй параметр - фильтруемое множество.

let numbers = set [-6; -5; -4; -3; -2; -1; 0; 1; 2; 3; 4; 5; 6]

// получаем только четные числа
let filteredSet = Set.filter (fun n -> n%2=0) numbers
printfn "%A" filteredSet    // set [-6; -4; -2; 0; 2; 4; 6]

Функция Set.partition позволяет получить два множества - одно с элементами, которые соответствуют условию, а второе множество с элементами, которые ему не соответствуют. Результатом является кортеж из двух множеств:

let numbers = set [-6; -5; -4; -3; -2; -1; 0; 1; 2; 3; 4; 5; 6]

// разбиваем на два множества - с четными и нечетными числами
let sets = Set.partition (fun n -> n%2=0) numbers
printfn "%A" (fst sets)    // set [-6; -4; -2; 0; 2; 4; 6]
printfn "%A" (snd sets)    // set [-5; -3; -1; 1; 3; 5]

А для преобразования множества применяется функция Set.map:

Set.map mapping set

В качестве первого параметра передается функция, которая получает каждый элемент множества и возвращает измененный элемент:

let numbers = set [0; 1; 2; 3; 4; 5; 6]

// возведем все числа в квадрат
let squares = Set.map (fun n -> n * n) numbers
printfn "%A" squares    // set [0; 1; 4; 9; 16; 25; 36]

Минимальный и максимальный элементы

F# позволяет легко получить минимальный и максимальный элементы множества. Для этого модуль Set предоставляет соответственно функции Set.minElement и Set.maxElement. В качестве альтернативы также можно использовать свойства MinimumElement и MaximumElement объекта Set.

Поскольку минимальный элемент - это тот, который условно меньше всех, то фактически он эквивалентен самому первому элементу множества. Аналогично максимальный элемент представляет последний элемент множества. Например:

let people = set ["Tom"; "Bob"; "Sam"]

printfn "Min: %s" (Set.minElement people)       // Min: Bob
printfn "Min: %s" people.MinimumElement       // Min: Bob

printfn "Max: %s" (Set.maxElement people)       // Max: Tom
printfn "Max: %s" people.MaximumElement      // Max: Tom

Операции с множествами

Кроме общих функций модуль Set предоставляет ряд функций для операций с двумя множествами:

  • Set.difference set1 set2: возвращает разницу двух множеств (элементы, которые есть в первом, но отсутствуют во втором множестве)

  • Set.intersect set1 set2: возвращает пересечение двух множеств (элементы, которые есть одновременно и в первом, и во втором множествам)

  • Set.intersectMany sets: возвращает пересечение всех множеств

  • Set.union set1 set2: возвращает объединение двух множеств (все элементы обоих множеств)

  • Set.unionMany sets: возвращает объединение всех множеств

Все эти функции возращают результат в виде нового множества.

И также есть ряд функций для проверки отношения множеств:

  • Set.isProperSubset set1 set2: возвращает true, если второе множество содержит первое множество, и при этом второе множество содержит как минимум один элемент, которого нет в первом

  • Set.isProperSuperset set1 set2: возвращает true, если первое множество содержит второе множество, и при этом первое множество содержит как минимум один элемент, которого нет в втором

  • Set.isSubset set1 set2: возвращает true, если второе множество содержит первое множество

  • Set.isSuperset set1 set2: возвращает true, если первое множество содержит второе множество

Объединение множеств

let students = set ["Tom"; "Bob"; "Sam"]
let employees = set ["Tom"; "Bob"; "Alex"; "Mike"]

// объединение множеств
let union1 = Set.union students employees
printfn $"{union}"                 // set [Alex; Bob; Mike; Sam; Tom]

В качестве альтернативы для объединения множеств можно применять операцию +:

let students = set ["Tom"; "Bob"; "Sam"]
let employees = set ["Tom"; "Bob"; "Alex"; "Mike"]

let union = students + employees
printfn $"{union}"                 // set [Alex; Bob; Mike; Sam; Tom]

Пересечение множеств

let students = set ["Tom"; "Bob"; "Sam"]
let employees = set ["Tom"; "Bob"; "Alex"; "Mike"]

let intersection = Set.intersect students employees
printfn $"{intersection}"           // set ["Bob", "Tom"]

Разность множеств

let students = set ["Tom"; "Bob"; "Sam"]
let employees = set ["Tom"; "Bob"; "Alex"; "Mike"]

let diff = Set.difference students employees
printfn $"{diff}"                  // set [Sam]

В качестве альтернативы для разности множеств можно применять операцию -:

let students = set ["Tom"; "Bob"; "Sam"]
let employees = set ["Tom"; "Bob"; "Alex"; "Mike"]

let diff = students - employees
printfn $"{diff}"                  // set [Sam]

Проверка отношения между множествами

Функция Set.isSubset и метод IsSubsetOf() объекта Set возвращают true, если первое множество содержится во втором (то есть первое множество является подмножеством второго):

let students = set ["Tom"; "Bob"; "Sam"]
let employees = set ["Tom"; "Bob"; "Alex"; "Mike"]

// является ли множество подмножеством
let workingStudents = Set.intersect students employees  // set ["Bob", "Tom"]

printfn "%b" (Set.isSubset workingStudents students)  // true
printfn "%b" (workingStudents.IsSubsetOf(students))  // true

printfn "%b" (Set.isSubset employees students)       // false
printfn "%b" (employees.IsSubsetOf(students))       // false

Функция Set.isSuperset и метод IsSupersetOf() объекта Set возвращают true, если второе множество содержится в первом (то есть первое множество является надмножеством второго):

let students = set ["Tom"; "Bob"; "Sam"]
let employees = set ["Tom"; "Bob"; "Alex"; "Mike"]

// является ли множество надмножеством
let people = Set.union students employees      // set ["Alex"; "Bob"; "Mike"; "Sam"; "Tom"]

printfn "%b" (Set.isSuperset people students)  // true
printfn "%b" (people.IsSupersetOf(students))  // true

printfn "%b" (Set.isSuperset employees students)  // false
printfn "%b" (employees.IsSupersetOf(students))  // false
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850