LISP - Установить

Common Lisp не предоставляет заданный тип данных. Однако он предоставляет ряд функций, которые позволяют выполнять операции над списком.

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

Реализация наборов в LISP

Наборы, как и списки, обычно реализуются в терминах cons-ячеек. Однако именно по этой причине операции над наборами становятся все менее и менее эффективными, чем больше становятся наборы.

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

В adjoinфункция сначала ищет элемент в данном списке, если он найден, то возвращает исходный список; в противном случае он создает новую cons-ячейку с ееcar как элемент и cdr указывая на исходный список и возвращает этот новый список.

В adjoin функция также принимает :key и :testаргументы ключевого слова. Эти аргументы используются для проверки наличия элемента в исходном списке.

Поскольку функция adjoin не изменяет исходный список, чтобы внести изменения в сам список, вы должны либо присвоить значение, возвращаемое функцией adjoin, исходному списку, либо вы можете использовать макрос pushnew добавить предмет в набор.

пример

Создайте новый файл исходного кода с именем main.lisp и введите в него следующий код.

; creating myset as an empty list
(defparameter *myset* ())
(adjoin 1 *myset*)
(adjoin 2 *myset*)

; adjoin did not change the original set
;so it remains same
(write *myset*)
(terpri)
(setf *myset* (adjoin 1 *myset*))
(setf *myset* (adjoin 2 *myset*))

;now the original set is changed
(write *myset*)
(terpri)

;adding an existing value
(pushnew 2 *myset*)

;no duplicate allowed
(write *myset*)
(terpri)

;pushing a new value
(pushnew 3 *myset*)
(write *myset*)
(terpri)

Когда вы выполняете код, он возвращает следующий результат -

NIL
(2 1)
(2 1)
(3 2 1)

Проверка членства

Группа функций позволяет вам проверить, является ли элемент членом набора или нет.

Ниже приведены синтаксисы этих функций -

member item list &key :test :test-not :key 
member-if predicate list &key :key 
member-if-not predicate list &key :key

Эти функции ищут в заданном списке заданный элемент, удовлетворяющий тесту. Если такой элемент не найден, функция возвращаетnil. В противном случае возвращается конец списка с элементом в качестве первого элемента.

Поиск ведется только на верхнем уровне.

Эти функции можно использовать как предикаты.

пример

Создайте новый файл исходного кода с именем main.lisp и введите в него следующий код.

(write (member 'zara '(ayan abdul zara riyan nuha)))
(terpri)
(write (member-if #'evenp '(3 7 2 5/3 'a)))
(terpri)
(write (member-if-not #'numberp '(3 7 2 5/3 'a 'b 'c)))

Когда вы выполняете код, он возвращает следующий результат -

(ZARA RIYAN NUHA)
(2 5/3 'A)
('A 'B 'C)

Установить союз

Группа функций union позволяет выполнять объединение наборов двух списков, предоставленных в качестве аргументов для этих функций, на основе теста.

Ниже приведены синтаксисы этих функций -

union list1 list2 &key :test :test-not :key 
nunion list1 list2 &key :test :test-not :key

В unionФункция принимает два списка и возвращает новый список, содержащий все элементы, присутствующие в любом из списков. Если есть дубликаты, то в возвращенном списке сохраняется только одна копия члена.

В nunion функция выполняет ту же операцию, но может уничтожить списки аргументов.

пример

Создайте новый файл исходного кода с именем main.lisp и введите в него следующий код.

(setq set1 (union '(a b c) '(c d e)))
(setq set2 (union '(#(a b) #(5 6 7) #(f h)) 
   '(#(5 6 7) #(a b) #(g h)) :test-not #'mismatch)
)
       
(setq set3 (union '(#(a b) #(5 6 7) #(f h)) 
   '(#(5 6 7) #(a b) #(g h)))
)
(write set1)
(terpri)
(write set2)
(terpri)
(write set3)

Когда вы выполняете код, он возвращает следующий результат -

(A B C D E)
(#(F H) #(5 6 7) #(A B) #(G H))
(#(A B) #(5 6 7) #(F H) #(5 6 7) #(A B) #(G H))

Пожалуйста, обратите внимание

Функция объединения не работает должным образом без :test-not #'mismatchаргументы для списка из трех векторов. Это потому, что списки состоят из cons-ячеек, и хотя значения кажутся нам одинаковыми,cdrчасть ячеек не совпадает, поэтому они не совпадают с интерпретатором / компилятором LISP. Это причина; не рекомендуется реализовывать большие наборы с использованием списков. Однако он отлично работает для небольших наборов.

Установить пересечение

Группа функций пересечения позволяет выполнять пересечение двух списков, предоставленных в качестве аргументов для этих функций на основе теста.

Ниже приведены синтаксисы этих функций -

intersection list1 list2 &key :test :test-not :key 
nintersection list1 list2 &key :test :test-not :key

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

пример

Создайте новый файл исходного кода с именем main.lisp и введите в него следующий код.

(setq set1 (intersection '(a b c) '(c d e)))
(setq set2 (intersection '(#(a b) #(5 6 7) #(f h)) 
   '(#(5 6 7) #(a b) #(g h)) :test-not #'mismatch)
)
       
(setq set3 (intersection '(#(a b) #(5 6 7) #(f h)) 
   '(#(5 6 7) #(a b) #(g h)))
)
(write set1)
(terpri)
(write set2)
(terpri)
(write set3)

Когда вы выполняете код, он возвращает следующий результат -

(C)
(#(A B) #(5 6 7))
NIL

Функция пересечения - это деструктивная версия пересечения, т. Е. Она может уничтожить исходные списки.

Установить разницу

Группа функций «набор-разность» позволяет вам выполнять разность наборов для двух списков, предоставленных в качестве аргументов для этих функций на основе теста.

Ниже приведены синтаксисы этих функций -

set-difference list1 list2 &key :test :test-not :key 
nset-difference list1 list2 &key :test :test-not :key

Функция set-difference возвращает список элементов первого списка, которых нет во втором списке.

пример

Создайте новый файл исходного кода с именем main.lisp и введите в него следующий код.

(setq set1 (set-difference '(a b c) '(c d e)))
(setq set2 (set-difference '(#(a b) #(5 6 7) #(f h)) 
   '(#(5 6 7) #(a b) #(g h)) :test-not #'mismatch)
)
(setq set3 (set-difference '(#(a b) #(5 6 7) #(f h)) 
   '(#(5 6 7) #(a b) #(g h)))
)
(write set1)
(terpri)
(write set2)
(terpri)
(write set3)

Когда вы выполняете код, он возвращает следующий результат -

(A B)
(#(F H))
(#(A B) #(5 6 7) #(F H))