400 likes | 419 Views
Learn about the formal definition of a list in Lisp, operations like cons, cdr, null, pair, and atom predicates, and basic list manipulation functions. Practice examples included.
E N D
Lecture 8 List and list operations (continue). מבוא מורחב - שיעור 8
Formal Definition of a List A list is either • ‘() -- The empty list • A pair whose cdr is a list. Note that lists are closed under the operations consand cdr. מבוא מורחב - שיעור 8
1 4 3 2 4 3 1 2 4 3 1 2 More Elaborate Lists (list 1 2 3 4) (cons (list 1 2) (list 3 4)) (list (list 1 2) (list 3 4)) מבוא מורחב - שיעור 8
The Predicate Null? null? : anytype -> boolean (null? <z>) #t if <z> evaluates to empty list #f otherwise (null? 2) #f (null? (list 1)) #f (null? (cdr (list 1))) #t (null? ’()) #t (null? null) #t מבוא מורחב - שיעור 8
The Predicate Pair? pair? : anytype -> boolean (pair? <z>) #tif <z> evaluates to a pair #f otherwise. (pair? (cons 1 2)) #t (pair? (cons 1 (cons 1 2))) #t (pair? (list 1)) #t (pair? ’()) #f (pair? 3) #f (pair? pair?) #f מבוא מורחב - שיעור 8
The Predicate Atom? atom? : anytype -> boolean (define (atom? z) (and (not (pair? z)) (not (null? z)))) (define (square x) (* x x)) (atom? square) #t (atom? 3) #t (atom? (cons 1 2)) #f מבוא מורחב - שיעור 8
Working with lists: some basic list manipulation מבוא מורחב - שיעור 8
(define (list-ref lst n) (if (= n 0) (car lst) (list-ref (cdr lst) (- n 1)))) Cdring Down a List 1 (list-ref (list 1 2 3) 0) Error (list-ref (list 1 2 3) 3) מבוא מורחב - שיעור 8
(define (length lst) (if (null? lst) 0 (+ 1 (length (cdr lst))))) Cdring Down a List, another example מבוא מורחב - שיעור 8
(define squares (list 1 4 9 16)) (define odds (list 1 3 5 7)) (append squares odds) (1 4 9 16 1 3 5 7) (append odds squares) (1 3 5 7 1 4 9 16) list2 list1 4 1 2 3 Can’t make this pointer Change, so… Consing Up a List (define (append list1 list2) (cond ((null? list1) list2); base (else (cons (car list1); recursion (append (cdr list1) list2))))) מבוא מורחב - שיעור 8
(append list1 list2) (cons 1 (append (2) list2)) (cons 1 (cons 2 (append () list2))) (cons 1 (cons 2 list2)) list2 list1 4 1 2 3 1 2 Append: process (define (append list1 list2) (cond ((null? list1) list2); base (else (cons (car list1); recursion (append (cdr list1) list2))))) • (define list1 (list 1 2)) • (define list2 (list 3 4)) (1 2 3 4) מבוא מורחב - שיעור 8
cons (car lst) 1 3 2 4 (reverse (cdr lst)) Wishful thinking… Reverse of a list (define (reverse lst) (cond ((null? lst) lst) (else ( (reverse (cdr lst)) ))))) cons (car lst) (reverse (list 1 2 3 4))
(reverse (cdr lst)) (list (car lst)) 3 2 4 1 1 3 2 4 Reverse of a list (define (reverse lst) (cond ((null? lst) lst) (else ( (reverse (cdr lst)) ))))) append (list (car lst)) (reverse (list 1 2 3 4)) (append ) Append: T(n) = c*n = (n) Reverse: T(n) = c*(n-1) + c*(n-2)+ … + c*1 = (n2)
(integers-between 2 4) (cons 2 (integers-between 3 4))) (cons 2 (cons 3 (integers-between 4 4))) (cons 2 (cons 3 (cons 4 (integers-between 5 4)))) (cons 2 (cons 3 (cons 4 null))) (2 3 4) 2 3 4 Enumerating (define (integers-between lo hi) (cond ((> lo hi) null) (else (cons lo (integers-between (+ 1 lo) hi))))) מבוא מורחב - שיעור 8
(enumerate-squares 2 4) (cons 4 (enumerate-squares 3 4))) (cons 4 (cons 9 (enumerate-squares 4 4))) (cons 4 (cons 9 (cons 16 (enumerate-squares 5 4)))) (cons 4 (cons 9 (cons 16 ‘()))) (4 9 16) 9 4 16 Enumerate Squares (define (enumerate-squares from to) (cond ((> from to) '()) (else (cons (square from) (enumerate-squares (+ 1 from) to))))) מבוא מורחב - שיעור 8
2 4 internal node 6 8 4 2 internal node leaf leaf 8 6 Trees • Abstract tree: • a leaf (a node that has no children, and contains data) - is a tree • an internal node (a node whose children are trees) – is a tree • Implementation of tree: • a leaf - will be the data itself • an internal node – will be a list of its children מבוא מורחב - שיעור 8
Count Leaves of a Tree • Strategy • base case: count of an empty tree is 0 • base case: count of a leaf is 1 • recursive strategy: the count of a tree is the sum of the countleaves of each child in the tree. • Implementation: (define (leaf? x) (atom? x)) מבוא מורחב - שיעור 8
4 2 5 7 Count Leaves (define (countleaves tree) (cond ((null? tree) 0) ;base case ((leaf? tree) 1) ;base case (else ;recursive case (+ (countleaves (car tree)) (countleaves (cdr tree)))))) (define my-tree (list 4 (list 5 7) 2)) מבוא מורחב - שיעור 8
+ (cl 4) (cl ((5 7) 2) ) (cl (5 7)) (cl (2)) + + (cl 2) (cl null) + + 4 2 (cl 7) (cl null) (cl (7)) (cl 5) 5 7 Countleaves my-tree (countleaves my-tree) ==> 4 (cl (4 (5 7) 2)) 4 3 1 2 1 1 1 1 0 1 0 מבוא מורחב - שיעור 8
Enumerate-Leaves • Goal: given a tree, produce a list of all the leaves • Strategy • base case: list of empty tree is empty list • base case: list of a leaf is one element list • otherwise, recursive strategy: build a new list from a list of the leaves of the first child and a list of the leaves of the rest of the children מבוא מורחב - שיעור 8
Enumerate-Leaves (define (enumerate-leaves tree) (cond ((null? tree) null) ;base case ((leaf? tree) ) ;base case (else ;recursive case ((enumerate-leaves (car tree)) (enumerate-leaves (cdr tree)))))) מבוא מורחב - שיעור 8
5 7 4 2 4 2 5 7 Enumerate-Leaves (define (enumerate-leaves tree) (cond ((null? tree) null) ;base case ((leaf? tree) (list tree)) ;base case (else ;recursive case (append(enumerate-leaves (car tree)) (enumerate-leaves (cdr tree)))))) מבוא מורחב - שיעור 8
ap (el 4) (el ((5 7) 2) ) ap (cl (5 7)) (el (2)) ap (el (7)) (el 5) (el 2) (el nil) ap (el 7) (el nil) Enumerate-leaves (el (4 (5 7) 2)) (4 5 7 2) (5 7 2) (4) (5 7) (2) ap (7) (5) (2) () (7) () מבוא מורחב - שיעור 8
Your Turn: Scale-tree • Goal: given a tree, produce a new tree with all the leaves scaled • Strategy • base case: scale of empty tree is empty tree • base case: scale of a leaf is product • otherwise, recursive strategy: build a new tree from a scaled version of the first child and a scaled version of the rest of children מבוא מורחב - שיעור 8
Scale-tree (define (scale-tree tree factor) (cond ((null? tree) ) ;base case ((leaf? tree) ) (else ;recursive case (cons )))) null (* tree factor) (scale-tree (car tree) factor) (scale-tree (cdr tree) factor) מבוא מורחב - שיעור 8
List abstraction • Find common high order patterns • Distill them into high order procedures • Use these procedures to simplify list operations Patterns: • Mapping • Filtering • Accumulating מבוא מורחב - שיעור 8
Mapping (define (map proc lst) (if (null? lst) null (cons (proc (car lst)) (map proc (cdr lst))))) (define (square-list lst) (map square lst)) (define (scale-list lst c) (map (lambda (x) (* c x)) lst)) (scale-list (integers-between 1 5) 10) ==> (10 20 30 40 50) מבוא מורחב - שיעור 8
Mapping: process (define (map proc lst) (if (null? lst) null (cons (proc (car lst)) (map proc (cdr lst))))) (map square (list 1 2 3)) (cons (square 1) (map square (list 2 3))) (cons 1 (map square (list 2 3))) (cons 1 (cons (square 2) (map square (list 3)))) (cons 1 (cons 4 (map square (list 3)))) (cons 1 (cons 4 (cons (square 3) (map square null)))) (cons 1 (cons 4 (cons 9 (map square null)))) (cons 1 (cons 4 (cons 9 null))) (1 4 9) מבוא מורחב - שיעור 8
Alternative Scale-tree • Strategy • base case: scale of empty tree is empty tree • base case: scale of a leaf is product • otherwise: a tree is a list of subtrees and use map. (define (scale-tree tree factor) (cond ((null? tree) null) ((leaf? tree) (* tree factor)) (else ;it’s a list of subtrees (map (lambda (child) (scale-tree child factor)) tree)))) מבוא מורחב - שיעור 8
Generalized Mapping (map <proc> <list1>…<listn>) Returns a list in which proc is applied to the i-th elements of the lists respectively. (map + (list 1 2 3) (list 10 20 30) (list 100 200 300)) ==> (111 222 333) (map (lambda (x y) (+ x (* 2 y))) (list 1 2 3) (list 4 5 6)) ==> (9 12 15) We will see how to write such a procedure later! מבוא מורחב - שיעור 8
(define (filter pred lst) (cond ((null? lst) null) ((pred (car lst)) (cons (car lst) (filter pred (cdr lst)))) (else (filter pred (cdr lst))))) Filtering (filter odd? (integers-between 1 10)) (1 3 5 7 9) מבוא מורחב - שיעור 8
(define (filter pred lst) (cond ((null? lst) null) ((pred (car lst)) (cons (car lst) (filter pred (cdr lst)))) (else (filter pred (cdr lst))))) Filtering: process (filter odd? (list 1 2 3 4)) (cons 1 (filter odd? (list 2 3 4))) (cons 1 (filter odd? (list 3 4))) (cons 1 (cons 3 (filter odd? (list 4)))) (cons 1 (cons 3 (filter odd? null))) (cons 1 (cons 3 null)) (1 3) מבוא מורחב - שיעור 8
2 3 4 5 6 7 8 9 10 2 X X 7 X XX 11 12 13 14 15 16 17 18 19 20 XX XX XX XX XX XX 21 22 23 24 25 26 27 28 29 30 XX XX XX XX XX XX XX 3 5 X X XX 31 32 33 34 35 36 37 38 39 40 XX XX XX XX XX XX XX XX XX XX XX 41 42 43 44 45 46 47 48 49 50 XX XX XX XX XX XX XX XX XX XX XX XX XX 51 52 53 54 55 56 57 58 59 60 XX XX XX XX XX XX XX XX XX XX XX 61 62 63 64 65 66 67 68 69 60 XX XX XX XX XX XX XX XX XX XX XX XX 71 72 73 74 75 76 77 78 79 80 XX XX XX XX XX XX XX XX XX XX XX XX 81 82 83 84 85 86 87 88 89 90 XX XX XX XX XX XX XX XX XX XX XX XX XX 91 92 93 94 95 96 97 98 99 100 XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX Finding all the Primes: Sieve of Eratosthenes (a.k.a. Beta) מבוא מורחב - שיעור 8
.. And here’s how to do it! (define (sieve lst) (if (null? lst) ‘() (cons (car lst) (sieve (filter (lambda (x) (not (divisible? x (car lst)))) (cdr lst)))))) ==> (sieve (list 2 3 4 5 … 100)) (cons 2 (sieve (filter (lambda (x) (not (divisible? X 2) (list 3 4 5 …100 )))) מבוא מורחב - שיעור 8
How sieve works (define (sieve lst) (if (null? lst) ‘() (cons (car lst) (sieve (filter (lambda (x) (not (divisible? x (car lst)))) (cdr lst)))))) • Sieve takes as argument a list of numbers L and returns a list M. • Take x, the first element of L and make it the first element in M. • Drop all numbers divisible by x from (cdr L). • Call sieve on the resulting list, to generate the rest of M. מבוא מורחב - שיעור 8
The Prime Number Theorem: (n) = Θ(n/log n) (For large n the constants are nearly 1) What’s the time complexity of sieve? (define (sieve lst) (if (null? lst) ‘() (cons (car lst) (sieve (filter (lambda (x) (not (divisible? x (car lst)))) (cdr lst)))))) Assume lst is (list 2 3 ... n). How many times is filter called? (n) (number of primes < n) מבוא מורחב - שיעור 8
T(n) = O( ) n2/log n What’s the time complexity of sieve? (cont’) (define (sieve lst) (if (null? lst) ‘() (cons (car lst) (sieve (filter (lambda (x) (not (divisible? x (car lst)))) (cdr lst)))))) Filter is called Θ(n/log n) times Filter is called Θ(n/log n) times for primes p ≤ n/2 (n/2+1..n) = (n) - (n/2) = Θ(n/log n) Each such call to filter does Ω(n/log n) work T(n) = Ω( n2 /(log n)2 ) The problem is that filter has to scan all of the list! מבוא מורחב - שיעור 8
66 (about two thirds) Another example Find the number of integers x in the range [1…100] s.t.: x * (x + 1) is divisible by 6. (length (filter _____________________________________ (map _________________________________ _________________________________)))) (lambda(n) (= 0 (remainder n 6))) (lambda(n) (* n (+ n 1))) (integers-between 1 100) Any bets on the result???? מבוא מורחב - שיעור 8
Accumulating Add up the elements of a list (define (add-up lst) (if (null? lst) 0 (+ (car lst) (add-up (cdr lst))))) Multiply all the elements of a list (define (mult-all lst) (if (null? lst) 1 (* (car lst) (mult-all (cdr lst))))) (define (accumulate op init lst) (if (null? lst) init (op (car lst) (accumulate op init (cdr lst))))) מבוא מורחב - שיעור 8
eln eln-1 init el1 …….. op op op ... op Accumulating (cont.) (define (accumulate op init lst) (if (null? lst) init (op (car lst) (accumulate op init (cdr lst))))) (define (add-up lst) (accumulate + 0 lst)) (define (mult-all lst) (accumulate * 1 lst)) מבוא מורחב - שיעור 8