|
This chapter has looked at defining functions on lists using recursion. Recursive function definitions are based on facts, and the facts for defining a function f on lists are equations of the form
where A and B are expressions. Since every list is either empty or nonempty, there are often two cases,
f ([ ]) | = | A | |
f (L) | = | B | (when L ≠ [ ]) |
where expression B refers to head(L) and tail(L). Sometime you need more equations to define f on nonempty lists.
Once you have equations that you believe are true (because you have checked them on example lists), it is easy to convert those equations to a C++ definition of your function. For example, suppose that removeAll(x, L) is intended to return the list of all members of list L, but with all occurrences of x omitted. For example, removeAll(5, [2, 5, 8, 4, 5, 3]) = [2, 8, 4, 3]. Equations are as follows.
(removeAll.1) | removeAll(x, [ ]) | = | [ ] | |
(removeAll.2) | removeAll(x, L) | = | removeAll(x, tail(L)) | (when head(L) = x) |
(removeAll.3) | removeAll(x, L) | = | head(L) : removeAll(tail(L)) | (when head(L) ≠ x) |
The second equation says, among other things, that
removeAll(2, [2, 4, 2, 4]) = removeAll(2, [4, 2, 4]) = [4, 4].The third equation says, among other things, that
removeAll(2, [5, 4, 2, 4]) = 5 : removeAll(2, [4, 2, 4]) = 5 : [4, 4] = [5, 4, 4].Conversion to C++ is simple and direct. There are three cases, one for each equation.
List removeAll(int x, List L) { if(L == NULL) { return NULL; } else if(x == head(L)) { return removeAll(x, tail(L)); } else { remove cons(head(L), removeAll(tail(L))); } }
|