(((a b) c) d (e (g)))At the top level, this list has three components, ((a b) c), d, and (e (f)). If we look within these components, we find there are a total of six symbols (the letters a through g). To count or otherwise process these symbols, procedures must work within sublists as well as working within the top level of the main list. As we have seen consistently, procedures in Scheme typically work recursively. Here, such procedures must apply recursion to components of lists as well as to the top-level components. Such processing is called deep recursion.
Goals: This laboratory exercise describes an example of deep recursion and provides experience applying this technique to several more examples.
Example: Consider the problem to count the number of times a given symbol appears in a list or any of its sublists. If this task were performed by procedure count-symbol, then this procedure should give the following results:
(count-symbol 'a '(((a b) c) a (a (b)))) ===> 3 (count-symbol 'b '(((a b) c) a (a (b)))) ===> 2 (count-symbol 'd '(((a b) c) a (a (b)))) ===> 0To attack this problem, we first identify an easy case: the empty list does not contain any symbol. This observation prompts the first part of some code for count-symbol:
(define count-symbol
(lambda (symbol ls)
(cond ((null? ls) 0)
;;; further conditions to be determined
)
)
)
If we do not encounter a null list, then it is possible to follow several
approaches. In one such approach, there are two main cases:
(define count-symbol
(lambda (symbol ls)
(cond ((null? ls) 0)
((list? (car ls)) (+ (count-symbol symbol (car ls))
(count-symbol symbol (cdr ls))))
((eq? symbol (car ls)) (+ 1 (count-symbol symbol (cdr ls))))
(else (count-symbol symbol (cdr ls)))
)
)
)
Steps for this Lab:
(define question-2
(lambda (ls)
(cond ((null? ls) #t)
((list? (car ls)) (and (question-2 (car ls))
(question-2 (cdr ls))))
((number? (car ls)) (question-2 (cdr ls)))
(else #f)
)
)
)
Write a procedure total that computes the sum of all numbers in a list or any sublist. In this problem, you may assume that any components will be either numbers or sublists. For example:
(total '()) ===> 0 (total '(1 (2 (3 (4 (5 6))) 7 8) 9)) ===> 45 (total '(1 2 (3 4 (8 9 0) 5 6) 7 8 9)) ===> 62
Write a procedure check-all-odd that replaces all numbers in a list or in any components to #t or #f, according to whether the number is odd. Non-numbers should be unchanged. For example,
(check-all-odd '(1 2 3 4 5 6 7 8 9 10)) ===>(#t #f #t #f #t #f #t #f #t #f) (check-all-odd '(((a (((5))))))) ===> (((a (((#t))))))) (check-all-odd '(7 (a (1/2 b) 3.14159) ((c -9)))) ===> (#t (a (#f b) #f) ((c #t))))
Write a procedure substitute-all that has three parameters, old, new, and ls and that returns a new list from ls with all occurences of old changed to new in the list or any sublist. Some examples follow:
(substitute-all 'the 'a '(the dog lives in the house)) ===> (a dog lives in a house) (substitute-all 8 9 '(1 2 (3 4 (8 9 0) 5 6) 7 8 9)) ===> (1 2 (3 4 (9 9 0) 5 6) 7 9 9) (substitute-all 0 9 '(1 (2 (3 (4 (5 6))) 7 8) 9)) ===> (1 (2 (3 (4 (5 6))) 7 8) 9)) (substitute-all 5 'b '(1 (2 (3 (4 (5 6))) 7 8) 9)) ===> (1 (2 (3 (4 (b 6))) 7 8) 9))
This document is available on the World Wide Web as
http://www.math.grin.edu/~walker/courses/151.fa00/lab-deep-recursion.html