ANSI Common Lisp: 4 Specialized Data Structures

advertisement
ANSI Common Lisp: 4 Specialized Data Structures
June 16, 2003
4.1 Define a function to take a square array (an array whose dimensions are ( n, n ) ) and rotate it
90  clockwise:
> (quarter-turn #2A((a b) (c d)))
#2A((C A) (D B))
You’ll need array-dimensions (page 361).
Solution:
(defun quarter-turn (arr)
(let* ((dim (array-dimensions arr))
; dimensions of original
array
(row (first dim))
; row # of original array
(col (second dim))
; column # of original array
(n row)
; dimension of original
array
new-arr)
(cond ((not (= row col))
; check if original array is a square
one
(format t "The argument is not a square array.~%"))
(t (setf new-arr (make-array dim :initial-element nil))
(do ((i 0 (+ i 1)))
((= i n))
(do ((j 0 (+ j 1)))
((= j n))
(setf (aref new-arr j i) (aref arr (- n i 1) j))))
new-arr))))
(quarter-turn #2A((a b) (c d)))
#2A((C A) (D B))
(quarter-turn #2A((a b c) (d e f) (g h i)))
#2A((G D A) (H E B) (I F C))
4.2 Read the description of reduce on page 368, then use it to define:
(a) copy-list
(b) reverse (for lists)
Solution:
1/4
(defun reduce-copy-list (lst)
(reduce #'(lambda (x y) (append x (list y))) lst :initial-value
()))
(defun reduce-reverse (lst)
(reduce #'(lambda (x y) (append y (list x))) lst :from-end t
:initial-value))
(reduce-copy-list '(1 2 (5 6) 3 4))
(1 2 (5 6) 3 4)
(reduce-reverse '(1 2 (5 6) 3 4))
(4 3 (5 6) 2 1)
4.3 Define a structure to represent a tree where each node contains some data and has up to three
children. Define
(a) a function to copy such a tree (so that no node in the copy is eql to a node in the original)
(b) a function that takes an object and such a tree, and returns true if the object is eql to the data
field of one of the nodes
Solution:
(defstruct (node (:print-function
(lambda (n s d)
(format s "#<~A,~A>" (node-elt1 n) (node-elt2
n)))))
elt1 elt2 (l nil) (m nil) (r nil))
(defun tree-copy (tree)
(if (not (null tree))
(let ((elt1 (node-elt1
(elt2 (node-elt2
(make-node
:elt1 elt1
:elt2 elt2
:l (tree-copy (node-l
:m (tree-copy (node-m
:r (tree-copy (node-r
tree))
tree)))
tree))
tree))
tree))))))
(defun tree-find (obj tree)
(when tree
(if (not (tree-find obj (node-l tree)))
(if (or (eql obj (node-elt1 tree)) (eql obj (node-elt2 tree)))
t
(if (not (tree-find obj (node-m tree)))
(if (or (eql obj (node-elt1 tree)) (eql obj (node-elt2
tree)))
2/4
t
(if (not (tree-find obj (node-r tree)))
(if (or (eql obj (node-elt1 tree)) (eql obj (nodeelt2 tree)))
t))))))))
4.4 Define a function that takes a BST and returns a list of its elements ordered from greatest to
least.
Solution:
(defun reverse-order (bst)
(reverse-order-recur '() bst))
(defun reverse-order-recur (lst bst)
(when bst
(setf lst (reverse-order lst (node-r bst)))
(setf lst (append lst (list (node-elt bst))))
(setf lst (reverse-order lst (node-l bst))))
lst)
(reverse-order nums)
(9 8 7 6 5 4 3 2 1)
4.5 Define bst-adjoin. This function should take the same arguments as bst-insert, but
should only insert the object if there is nothing eql to it in the tree.
Solution:
(defun bst-adjoin (obj bst <)
(if (not (bst-find obj bst #'<))
(bst-insert obj bst #'<)))
4.6 The contents of any hash table can be described by an assoc-list whose elements are (k . v), for
each key-value pair in the hash table. Define a function that
(a) takes an assoc-list and returns a corresponding hash table.
(b) takes a hash table and returns a corresponding assoc-list
Solution:
(defun alist-hashtable (lst)
(let ((ht (make-hash-table)))
(dolist (item lst)
3/4
(setf (gethash (car item) ht) (cdr item)))
ht))
(defun hashtable-alist (ht)
(let ((alist '()))
(maphash #'(lambda (key value)
(setf alist (append alist (list (cons key value)))))
ht)
alist))
4/4
Download