400 likes | 494 Views
Functional Programming . 03 Specialized Data Structures. Review. Breadth First Search (BFS) Implementation: FIFO Queue Shortest path searching Depth First Search (DFS) Implementation: LIFO Stack. Specialized Data Structures -Arrays. make-array
E N D
Functional Programming 03 Specialized Data Structures
Review • Breadth First Search (BFS) • Implementation: FIFO Queue • Shortest path searching • Depth First Search (DFS) • Implementation: LIFO Stack
Specialized Data Structures -Arrays • make-array • > (setfarr (make-array ‘(2 3) :initial-element nil))#<Array T (2 3)> • Maximum: • 7 dimensions • Each dimension can have 1023 elements • Initial-element • Optional • Whole array will be initialized to this value • > (arefarr 0 0)NIL
Specialized Data Structures -Arrays • > (setf(arefarr 0 0) ‘b)B • > (arefarr 0 0) ; access the arrayB • #na • Denote an n-dimensional array • E.g., 2a ((b nil nil) (nil nilnil)) • If *print-array* is t, arrays will be displayed in this form: • > (setf *print-array* t)T • > arr#2A ((B NIL NIL) (NIL NILNIL))
Specialized Data Structures -Arrays • One-dimensional array • > (setfvec (make-array 4 :initial-element nil))#(NIL NILNILNIL) • > (vector “a” ‘b 5 “c”)#(“a” B 5 “c”) • > (setfvec (vector “a” ‘b 5 “c”)) > (svrefvec 1) ;access the vector (sv: simple vector)B
Specialized Data Structures –Arrays: Binary Search • (defun bin-search (objvec) (let ((len (length vec))) (and (not (zeroplen)) (finder objvec 0 (- len 1))))) • (defun finder (obj vecstart end) (let ((range (- end start))) (if (zerop range) (if (eqlobj (arefvec start)) obj nil) (let ((mid (+ start (round (/ range 2))))) (let ((obj2 (arefvec mid))) (if (< obj obj2) (finderobjvecstart (- mid1)) (if (> obj obj2) (finderobjvec(+ mid 1) end) obj)))))))
Specialized Data Structures –Arrays: Binary Search • Insert the follow line at the beginning of finder(format t “~A~%” (subseqvec start (+ end 1))) • > (bin-search 3 #(0 1 2 3 4 5 6 7 8 9))#(0 1 2 3 4 5 6 7 8 9)#(0 1 2 3)#(3)3
Specialized Data Structures –Arrays: Binary Search • ;;;; Utilities for operations on sorted vectors. ;;; Finds an element in a sorted vector. (defun bin-search (objvec) (let ((len (length vec))) ;; if a real vector, send it to finder (and (not (zeroplen)) ; returns nil if empty (finder objvec 0 (- len 1)))))
Specialized Data Structures – Strings and Characters • String: a vector of characters • > (sort “elbow” #’char<)“below” • Retrieve an element of a string • > (aref “abc” 1)#\b • > (char “abc” 1)#\b
Specialized Data Structures – Strings and Characters • Replace elements of a stirng • > (let ((str (copy-seq “Merlin”))) (setf (char str 3) #\k)str)“Merkin” • Compare two strings • > (equal “fred” “fred”)T • > (equal “fred” “Fred”)NIL • > (string-equal “fred” “Fred”)T
Specialized Data Structures – Strings and Characters • Building strings • > (format nil “~A or ~A” “truth” “dare”)“truth or dare” • > (concatenate ‘string “not “ “to worry”)“not to worry”
Specialized Data Structures – Sequences • Find the position of an element in a sequence • > (position #\a “fantasia”)1 • > (position #\a “fantasia” :start 3 :end 5)4
Specialized Data Structures – Sequences • > (position #\a “fantasia” :from-end t)7 • > (position ‘a ‘((c d) (a b)) :key #’car)1; :key argument is a function that is applied to each ;element of a sequence before it is considered,; that is, whose car is symbol a • > (position ‘(a b) ‘((a b) (c d)))NIL • > (position ‘(a b) ‘((a b) (c d)) :test #’equal)0 • > (position 3 ‘(1 0 7 5) :test #’<) • ? • 2
Specialized Data Structures – Sequences • Write a function using subseq and position, which returns the second word in a string • (defun second-word (str) (let ((p1 (+ (position #\ str) 1))) (subseqstr p1 (position #\ str :start p1)))) • > (second-word “From follows function.”)“follows”
Specialized Data Structures – Sequences • > (position-if #’oddp ‘(2 3 4 5))1;it takes all the keyword argument except :test • > (find #\a “cat”)#\a • > (find-if #’characterp “ham”)#\h • Often a call to find-if will be clearer if it is translated into a find with a :key argument • (find-if #’(lambda (x) (eql (car x) ‘complete))lst) • (find ‘complete lst :key #’car)
Specialized Data Structures – Sequences • > (remove-duplicates “abracadabra”)“cdbra”; preserve only the last of each occurrence of any element of a sequence • (reduce #’fn ‘(a b c d))is equivalent to (fn (fn (fn ‘a ‘b) ‘c) ‘d) • > (reduce #’intersection ‘((b r a d ‘s) (b a d) (c a t)))(A)
Specialized Data Structures – Sequences: Parsing Dates • Write a program: • Takes a string like “16 Aug 1980” • Returns a list of integers representing the day, month, and year, like (16 8 1980) • > (parse-date “16 Aug 1980”)(16 8 1980)
Specialized Data Structures – Sequences: Parsing Dates • (defun tokens (str test start) (let ((p1 (position-if test str :start start))) (if p1 (let ((p2 (position-if #’(lambda (c) (not (funcall test c)))str :start p1))) (cons (subseqstr p1 p2) (if p2 (tokens str test p2) nil))) nil))) • (defun constituent (c) (and (graphic-char-p c) (not (char= c #\ ))))
Specialized Data Structures – Sequences: Parsing Dates • > (tokens “ab12 3cde.f” #’alpha-char-p 0)(“ab” “cde” “f”) • > (tokens “ab12 3cde.f gh” #’constituent 0)(“ab12” “3cde.f” “gh”) • In Common Lisp, graphic characters are all the characters we can see, plus the space character
Specialized Data Structures – Sequences: Parsing Dates • (defun parse-date (str) (let ((toks (tokens str #’constituent 0))) (list (parse-integer (first toks)) (parse-month (second toks)) (parse-integer (third toks))))) • (defconstant month-names #(“jan” “feb” “mar” “apr” “may” “jun” “jul” “aug” “sep” “oct” “nov” “dec”)) • (defun parse-month (str) (let ((p (position str month-names :test #’string-equal))) (if p (+ p 1) nil)))
Specialized Data Structures – Sequences: Parsing Dates • parse-integer • Takes a string and returns the corresponding integer • (defun read-integer (str) (if (every #’digit-char-p str) (let ((accum 0)) (dotimes (pos (length str)) (setfaccum (+ (* accum 10) (digit-char-p (char str pos)))))accum) nil))
Specialized Data Structures – Structures • (defstruct point x y) • (setf p (make-point :x 0 :y 0))#S(POINT X 0 Y 0) • > (point-x p)0 • > (setf (point-y p) 2)2 • > p#S(POINT X 0 Y 2) • > (point-p p)T • > (typep p ‘point)T
Specialized Data Structures – Structures • (defstruct polemic (type (progn (format t “What kind of polemic was it?”) (read))) (effect nil)) • > (make-polemic)What kind of polemic was it? scathing#S(POLEMIC TYPE SCATHING EFFECT NIL)
Specialized Data Structures – Structures • (defstruct (point (:conc-name p) (:print-function print-point)) (x 0) (y 0))(defun print-point (p stream depth) (format stream “#<~A,~A>” (px p) (py p))) • > (make-point)#<0,0>
Specialized Data Structures – Structures: Binary Search Trees
Specialized Data Structures – Structures: Binary Search Trees (defstruct (node (:print-function (lambda (n s d) (format s "#<~A>" (node-elt n))))) elt (l nil) (r nil)) (defunbst-insert (objbst <) (if (null bst) (make-node :eltobj) (let ((elt (node-eltbst))) (if (eqlobjelt) bst (if (funcall < objelt) (make-node :eltelt :l (bst-insert obj (node-l bst) <) :r (node-r bst)) (make-node :eltelt :r (bst-insert obj (node-r bst) <) :l (node-l bst)))))))
Specialized Data Structures – Structures: Binary Search Trees (defunbst-find (objbst <) (if (null bst) nil (let ((elt (node-eltbst))) (if (eqlobjelt) bst (if (funcall < objelt) (bst-find obj (node-l bst) <) (bst-find obj (node-r bst) <)))))) (defunbst-min (bst) (and bst (or (bst-min (node-l bst)) bst))) (defunbst-max (bst) (and bst (or (bst-max (node-r bst)) bst)))
Specialized Data Structures – Structures: Binary Search Trees • Build a BST • > (setfnums nil)NIL • > (dolist (x ‘(5 8 4 2 1 9 6 7 3)) (setfnums (bst-insert x nums #’<)))NIL • Search an element in a BST • > (bst-find 12 nums #’<)NIL • > (bst-find 4 nums #’<)#<4> • > (bst-min nums)#<1> • >(bst-max nums)#<9>
Specialized Data Structures – Structures: Binary Search Trees (defunbst-remove (objbst <) (if (null bst) nil (let ((elt (node-eltbst))) (if (eqlobjelt) (percolate bst) (if (funcall < objelt) (make-node :eltelt :l (bst-remove obj (node-l bst) <) :r (node-r bst)) (make-node :eltelt :r (bst-remove obj (node-r bst) <) :l (node-l bst)))))))
Specialized Data Structures – Structures: Binary Search Trees (defun percolate (bst) (cond ((null (node-1 bst)) (if (null (node-r bst)) nil (rpercbst))) ((null (node-r bst)) (lpercbst)) (t (if (zerop (random 2)) (lpercbst) (rpercbst))))) (defunrperc (bst) (make-node :elt (node-elt (node-r bst)) :l (node-l bst) :r (percolate (node-r bst)))) (defunlperc (bst) (make-node :elt (node-elt (node-l bst)) :l (percolate (node-l bst)) :r (node-r bst)))
Specialized Data Structures – Structures: Binary Search Trees • Remove an element from a BST • > (setfnums (bst-remove 2 nums #’<))#<5> • > (bst-find 2 nums #’<)NIL
Specialized Data Structures – Structures: Binary Search Trees • (defunbst-traverse (fn bst) (when bst (bst-traverse fn (node-l bst)) (funcall fn (node-eltbst)) (bst-traverse fn (node-r bst)))) • > (bst-traverse #’princnums)13456789NIL
Specialized Data Structures – Hash Tables • Create a hash table • > (setf ht (make-hash-table))#<Hash-Table #x1A54D24D> • Retrieve the value associated with a given key • > (gethash ‘color ht)NIL → the value associated with the keyNIL → whether the hash table has any value stored under that key
Specialized Data Structures – Hash Tables • Associate a value with a key • > (setf (gethash ‘color ht) ‘red)RED> (gethash ‘color ht)REDT • > (setf bugs (make-hash-table))#<Hash-Table #x1A54D585>> (push “Doesn’t take keyword arguments.” (gethash #’our-member bugs))(“Doesn’t take keyword arguments.”) → push new strings into the entry for a function
Specialized Data Structures – Hash Tables • Use hash table to represent sets • When the sets become large, lookups and deletions should be much fasterwith hash tables • > (setf fruit (make-hash-table))#<Hash-Table #x1A54DA778>> (setf (gethash ‘apricot fruit) t)T> (gethash ‘apricot fruit)TT> (remhash ‘apricot fruit) ;remove an entry from a hash tableT
Specialized Data Structures – Hash Tables • maphash • Takes a function of two arguments and a hash table, and this function will be called on every key/value pair in the tale • > (setf (gethash ‘shape ht) ‘spherical (gethash ‘size ht) ‘giant)GIANT> (maphash #’(lambda (k v) (format t “~A = ~A~%” k v)) ht)SHAPE = SPHERICALSIZE = GIANTCOLOR = REDNIL
Specialized Data Structures – Hash Tables • :size • specifies the number of elements • (make-hash-table :size 1000) • :test • > (setf writers (make-hash-table :test #’equal))#<Hash-Table #xA354553>> (setf (gethash ‘(ralphwaldoemerson) writers) t)T
Specialized Data Structures • Homework (Due March 31) • Define a function that takes a BST and returns a list of its elements ordered from greatest to least • List the syntax mappings between Lisp and C (or any other languages that you are familiar with) as many as possible • Illustrate what happened while removing the root node (5) of the tree in page 25 by the algorithm introduced in our class. If the resulting tree is wrong (not a BST), explain why • Debug the function “bin-search” or “finder” in page 6 to enable a correct searching, even if the obj is smaller than all elements in vec
BST-Remove (defunbst-remove (objbst) (if (null bst) nil (let ((elt (node-eltbst))) (if (eqlobjelt) (percolate bst) (if (< objelt) (make-node :eltelt :l (bst-remove obj (node-l bst)) :r (node-r bst)) (make-node :eltelt :r (bst-remove obj (node-r bst)) :l (node-l bst)))))))
(defun percolate (bst) (cond ((null (node-l bst)) (if (null (node-r bst)) nil (rpercbst))) ((null (node-r bst)) (lpercbst)) (t (if (zerop (random 2)) (lpercbst) (rpercbst))))) (defunrperc (bst) (setf min-node-of-r (bst-min (node-r bst))) (make-node :elt (node-elt min-node-of-r) :l (node-l bst) :r (bst-remove (node-elt min-node-of-r) (node-r bst)))) (defunlperc (bst) (setf max-node-of-l (bst-max (node-l bst))) (make-node :elt (node-elt max-node-of-l) :r (node-r bst) :l (bst-remove (node-eltmax-node-of-l) (node-l bst))))