140 likes | 150 Vues
6001 structure & interpretation of computer programs recitation 12/ november 4, 1997. topics. mutable data structures finish circular buffer example from last time sample quiz problems patterns, representations, tree search, streams. 1. 6. 2. 5. 3. 4. circular buffer (from last time).
E N D
6001structure & interpretation of computer programsrecitation 12/ november 4, 1997
topics • mutable data structures • finish circular buffer example from last time • sample quiz problems • patterns, representations, tree search, streams
1 6 2 5 3 4 circular buffer (from last time) • model • always contains at least one element • values inserted to right of bar • values removed from right of bar • basic operations • make-circular-buffer : T –> CB • insert! : CB x T –> undefined • remove! : CB –> T • rotate-left! : CB –> undefined • rotate-right! : CB –> undefined • size : CB –> int • implementation hints • use only a singly-linked list • all ops are 0(1) time except for rotate-right! and size
implementation • notes • represent each entry as a cons cell • represent buffer as a cons cell whose car (cdr) is the cell to the left (right) of the bar • code • (define (make-cb v) • (let ((cell (cons v nil))) • (set-cdr! cell cell) • (cons cell cell))) • (define (insert! b v) • (let ((new-cell (cons v (cdr b)))) • (set-cdr! (car b) new-cell) • (set-cdr! b new-cell))) • (define (remove! b) • (let ((old-cell (cdr b))) • (set-cdr! (car b) (cdr old-cell)) • (set-cdr! b (cdr old-cell)) • (car old-cell)))
implementation, ctd • (define (size b) • (define (count cell) • (if (eq? (car b) cell) • 1 • (inc (count (cdr cell))))) • (count (cdr b))) • ; a hidden operation: (prev c) is the cell that precedes c • (define (prev c) • (define (follow current) • (let ((next (cdr current))) • (if (eq? c next) • current • (follow next))))
implementation, ctd • (define (rotate-left! b) • (set-car! b (cdr b)) • (set-cdr! b (cddr b))) • (define (rotate-right! b) • (set-cdr! b (car b)) • (set-car! b (prev (car b))))
sample problems: pattern matching (1) • problem • Write a simplified version of (match pat dat) which takes • iin two args, both lists, representing the pattern & the datum. • The pattern has ?, ?variable & symbols. The datum has symbols. • It returns #f if there is no dictionary or it returns the • appropriate dictionary. • You can assume you have a procedure • (insert var val d) that returns a new dictionary obtainined by adding • the pair (var, val) to d, unless var is already there, in which case it • returns d if (var, val) is present and #f otherwise. • You can also assume that you have primitive procedures var?, anon-var? • that take a symbol and return true if the symbol is a variable, anonymous • variable • examples • (match '(? ?a b c ?d) '(hi there b c hello)) ==> ((?a there) (?d hello)) • (match '(? ?a b c ?d) '(hi there b bad hello))==> #f
sample problems: pattern matching (2) • solution • (define (match pat dat)(cond ((not (eq? (length pat) (length dat))) #f) • ((null? pat) ‘()) (let ((d (match (cdr pat) (cdr dat)))) (if (not d) d (cond ((var? (car pat)) (insert (car pat) (car dat) d)) ((anon-var? (car pat)) d) ((eq? (car pat) (car dat)) d) (else #f))))))
sample problems: pattern matching (3) • problem • Write a simplified version of (instantiate temp dict) • which takes in two args, a template, which is a list of • ?variables & symbols and dict which is a dictionary that • better have all the ?variables mentioned in the template. • It returns the template with the variables substituted • appropriately. • example • (instantiate '(this ?is a ?test) '((?is hi) (?test hello) (?other ignored))) • ==> (this hi a hello) • solution • (define (instantiate temp dict)(define (lookup v) (cadr (assq v dict)))(map lookup temp))
sample problems: mutable bag • Design a Data Structure for.... • & implement (or provide a sketch of how it works) the following functions: • Represent a mutable bag of elements. A bag is like a set with duplicates. • Create empty bag - O(1) • add element to bag - O(n) where n is number of distinct elements in bag • return total # of elements - O(n) • return # of distinct elements - O(n) • delete an element - O(n) • determine how many occurences of a particular element are in the bag - O(n) • After you have something that works with those time bounds, • see if you can improve (by changing slightly the data structure) • the time bounds for return total # of elements & return • # of distinct elements to O(1) • Can you think of other useful operations on the bag?
sample problem: tree search • problem • a tree consists of a key, a value and a list of subtrees • write a search procedure that takes a tree and a key and returnsa list of all values associated with the key • assume you have proceduresempty?, key, value, nextwhere (next t) returns the subtrees of t • code • (define (search t k)(define (dfs trees) (if (null? trees) • nil (let ((t1 (car trees))) (if (eq? (key t1) k) (cons (val t1) (dfs (append (next t1) (cdr trees)))) (dfs (append (next t1) (cdr trees))))))) • (dfs (list t)))
sample problem: streams (1) • problem • what does map-stream do? • what is its type? • implement it using the primitives car-stream, cdr-stream, cons-stream • solution • map-stream : (t1 -> t2) x stream(t1) –> stream(t2) • (define (map-stream p s)(cons-stream (p (car-stream s)) (map-stream p (cdr-stream s))))
sample problem: streams (2) • problem • take the tree from before • define a procedure that converts a tree to a stream • containing key/value pairs in depth first order. • use this to implement depth-frst search • code • (define (streamify t k)(define (dfs trees) (if (null? trees) • the-empty-stream • (let ((t1 (car trees))) (cons-stream (cons (key t1) (val t1)) (dfs (append (next t1) (cdr trees))))))) (dfs (list t))) • (define (search t k)(filter-stream (lambda (e) (eq? (key e) k)) (streamify t)))
sample problem: procedures with state • problem • write a procedure that takes a procedure p of one argument • and returns another procedure, that behaves exactly like p • except when presented with the argument ‘how-many, • which causes it to return the number of times p has been called. • example • (define sc (counter square)) • (sc 3) ==> 9 • (sc 4) ==> 16 • (sc ‘how-many) ==> 2 • solution • (define (counter p)(let ((ct 0)) (lambda (i) (if (eq? i ‘how-many) ct (begin (set! ct (inc ct)) (p i))))))