Lisp - Adding element to a Set



Lisp is not having Set as built-in data structure but we can implement a Set using List. We can add elements to the Set while maintaining the set property that is no duplicate value is allowed in a Set. In this chapter, we'll disucss various methods to add an element to a set.

Using adjoin function

  • adjoin function is the most commonly used method to add an element to the set.

  • adjoin function first checks if an element is already present in the list or not. If element is present, same list is returned without any modification otherwise element is added at the beginning of the list and a new list is returned.

  • By this way adjoin function maintains the set property.

  • adjoin function is used in conjuction with setf function to modify a set variable to reflect the changes.

main.lisp

; define a set of 3 elements with given list of values
(defvar my-set '(1 2 3))

; print the set
(print my-set)

; add a new value
(setf my-set (adjoin 4 my-set))

(terpri)
; print the updated set
(print my-set)

; try to add a duplicate value
(setf my-set (adjoin 2 my-set))

(terpri)
; print the set, still no duplicate
(print my-set)

Output

When you execute the code, it returns the following result −

(1 2 3) 
(4 1 2 3) 
(4 1 2 3) 

Using pushnew function

  • pushnew function can also be used to add an element to the set maintaining the set property.

  • pushnew function first checks if an element is already present in the list or not. If element is present, list is not updated otherwise element is added.

  • By this way pushnew function maintains the set property.

  • pushnew function is used without setf function to modify a set variable to reflect the changes.

main.lisp

; define a set of 3 elements with given list of values
(defvar my-set '(1 2 3))

; print the set
(print my-set)

; add a new value
(pushnew 4 my-set)

(terpri)
; print the updated set
(print my-set)

; try to add a duplicate value
(pushnew 2 my-set)

(terpri)
; print the set, still no duplicate
(print my-set)

Output

When you execute the code, it returns the following result −

(1 2 3) 
(4 1 2 3) 
(4 1 2 3) 

Using custom function to add element to Set

We can define a custom function as well while checking the element in a list as shown below −

main.lisp

; define a function 
(defun add (element set)
  ; if element is a member of set return the set
  (if (member element set)
      set
      ; otherwise add element to the list
      (cons element set)))

; define a set of 3 elements with given list of values
(defvar my-set '(1 2 3))

; print the set
(print my-set)

; add a new value
(setf my-set (add 4 my-set))

(terpri)
; print the updated set
(print my-set)

; try to add a duplicate value
(setf my-set (add 2 my-set))

(terpri)
; print the set, still no duplicate
(print my-set)

Output

When you execute the code, it returns the following result −

(1 2 3) 
(4 1 2 3) 
(4 1 2 3) 

Key Considerations

  • Order− A List is not preserving the order of element so in a Set implemented using List, order of elements in a Set is not gurranteed.adjoin and pushnew functions add element to the beginning of the List. Although we can use sort function to sort the list and maintain an order with elements.

  • Equalityadjoin and pushnew functions internally use member function to check an existing element. And member function uses eql method for comparison. Using :test we can use any other equality method to compare elements.

  • Efficiency− A list based implementation of a large Set can be inefficient during membership check. For high performance, hashtable or tree can be used to represent a Set.

Advertisements