170 likes | 288 Views
Imperative Data Structures. “Get your data structures correct first, and the rest of the program will write itself.” -Davids Johnson, Assen, The Netherlands. Why Does LISP Need Them?. Lists can represent any combination of data you could need Strings and arrays are just lists of data
E N D
Imperative Data Structures “Get your data structures correct first, and the rest of the program will write itself.” -Davids Johnson, Assen, The Netherlands
Why Does LISP Need Them? • Lists can represent any combination of data you could need • Strings and arrays are just lists of data • Association lists are like hash tables because you can look up values by keys • But they are inefficient • Can only access at the front • The simplest access operations are linear time on average
Strings • We already used strings in our IO operations, and we know how to return them using format >(format nil "Blah Blah ~A" "Blah") "Blah Blah Blah" • Strings are one instance of a sequence: • Lists, strings, arrays and vectors are sequences • But strings are still atomic • (atom "String") →T
String Functions • (char s i) returns the ith character of string s (zero-based index) • With setf, can be used to destructively modify character in a string • (string c) takes a character c and returns a string containing the single character represented by c
Make-String • You can create strings of a specified size using make-string >(make-string 10) " " • You can specify an initial element using the appropriate keyword • Default is #\Space (depends on implementation) >(make-string 10 :initial-element #\h) "hhhhhhhhhh"
Intern • (intern s) returns the corresponding symbol for a given string s • If the symbol already exists, a second value of :INTERNAL is returned • Otherwise a second value of NIL is returned >(intern "A") A NIL >(intern "A") A :INTERNAL >(intern "a") |a| NIL
String-Trim • Removes leading and trailing characters from a string • First argument is characters to remove, second is string to remove from >(string-trim "24" "2 3 3 4") " 3 3 " >(string-trim "24 " "2 3 3 4") "3 3" >(string-trim "24 3" "2 35353 4") "535" • string-left-trim and string-right-trim also exist
Arrays • A single dimensional array is a vector • Strings are vectors of characters • Create arrays using make-array • (make-array n) makes a vector of size n • (make-array '(n1 n2 n3 …)) makes a multi-dimensional array with sizes n1, n2, n3, etc. along the corresponding dimensions • :initial-element allows specification of a uniform initial value (default nil;depends on implementation) • :initial-contents allows you to fully specify the initial contents as a list
Make-Array Examples >(make-array 9) #(NIL NIL NIL NIL NIL NIL NIL NIL NIL) >(make-array 9 :initial-element 5) #(5 5 5 5 5 5 5 5 5) >(make-array '(3 2)) #2A((NIL NIL) (NIL NIL) (NIL NIL)) >(make-array 3 :initial-contents '(1 3 5)) #(1 3 5) >(make-array '(2 2) :initial-contents '((1 3) (2 4))) #2A((1 3) (2 4)) >(make-array '(2 2) :initial-contents '(1 2 3)) Error
Accessing Array Elements • aref is used to access array elements • An index is needed for each dimension of the array >(setf x (make-array '(3 2) :initial-contents '((1 2) (3 4) (5 6)))) #2A((1 2) (3 4) (5 6)) >(aref x 0 0) 1 >(aref x 3 1) Error >(aref x 2 1) 6
Vectors • One-dimensional arrays • Can create and fill using vector >(vector "a" 3 'foo) #("a" 3 FOO) • Can access vectors using aref, but can also use the faster svref for vectors
Position • Search for an element in any sequence • Keyword arguments include :key, :test, :from-end, :start and :end >(position #\o "location") 1 >(position #\o "location" :start 2) 6 >(position #\o "location" :start 2 :end 4) NIL >(position #\o "location" :from-end t) 6 >(position 'a '((c d) (a b)) :key #'car) 1 >(position '(a b) '((c d) (a b)) :test #'equal) 1
Other Sequence Functions • We’ve already seen subseq, remove and remove-if • Others include position-if, find, find-if • reducefolds a sequence into a single value • (reduce #'fn '(a b c d)) is the same as (fn (fn (fn 'a 'b) 'c) 'd) >(reduce #'cons '(a b c d e)) ((((A . B) . C) . D) . E)
Hash Tables • More efficient than association lists • Create using make-hash-table • Access using get-hash • Add entries using setf on the get-hash • Remove elements using remhash
Make-Hash-Table >(make-hash-table) #<hash-table 083cae8c> • Can set initial size using :size • Can change the test used for looking up entries using :test • Default is eql
Hash Table Examples >(setf ht (make-hash-table)) #<hash-table 083caa2c> >(gethash 'color ht) NIL NIL >(setf (gethash 'color ht) 'red) RED >(gethash 'color ht) RED T >(remhash 'color ht) T
Maphash • Maphash takes a function of two arguments and a hash table and calls that function on every key/value pair in the table, in no particular order >(setf (gethash 'shape ht) 'round) ROUND >(setf (gethash 'size ht) 30) 30 >(maphash #'(lambda (k v) (format t "~A = ~A~%" k v)) ht) SIZE = 30 SHAPE = ROUND NIL