211 lines
7.4 KiB
HTML
211 lines
7.4 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3O//DTD W3 HTML 2.0//EN">
|
|
<!Originally converted to HTML using LaTeX2HTML 95 (Thu Jan 19 1995) by Nikos Drakos (nikos@cbl.leeds.ac.uk), CBLU, University of Leeds >
|
|
<HEAD>
|
|
<TITLE> Recursion on Simple Lists</TITLE>
|
|
</HEAD>
|
|
<BODY>
|
|
<meta name="description" value=" Recursion on Simple Lists">
|
|
<meta name="keywords" value="lp">
|
|
<meta name="resource-type" value="document">
|
|
<meta name="distribution" value="global">
|
|
<P>
|
|
<BR> <HR>
|
|
<A HREF="node44.html"><IMG ALIGN=BOTTOM ALT="next" SRC="next_motif.gif"></A>
|
|
<A HREF="node41.html"><IMG ALIGN=BOTTOM ALT="up" SRC="up_motif.gif"></A>
|
|
<A HREF="node42.html"><IMG ALIGN=BOTTOM ALT="previous" SRC="previous_motif.gif"></A> <BR>
|
|
<A HREF="lp.html"><B>Contents</B></A>
|
|
<B> Next:</B>
|
|
<A HREF="node44.html"> Recursion on Nested </A>
|
|
<B>Up:</B>
|
|
<A HREF="node41.html"> Programming Techniques</A>
|
|
<B> Previous:</B>
|
|
<A HREF="node42.html"> A Word about </A>
|
|
<BR> <HR> <P>
|
|
<H1> Recursion on Simple Lists</H1>
|
|
<P>
|
|
Lists are one of the basic data structures in Lisp. Very often
|
|
programmers need to manipulate lists. Think of the broad possibility
|
|
of operations one may want to perform on lists: counting the number
|
|
of elements in a list; searching for an element in a list; removing a
|
|
particular element from a list; replacing an element in a list; these
|
|
represent only a small number of possibilities. All of these problems
|
|
are inherently recursive. Also, their solutions all follow the same
|
|
structure.
|
|
<P>
|
|
<BLOCKQUOTE>
|
|
<PRE><TT> <H4><b>RULE OF THUMB 1:
|
|
<P>
|
|
When recurring on a list, do three things:
|
|
<P>
|
|
1. check for the termination condition;
|
|
<P>
|
|
2. use the first element of the list;
|
|
<P>
|
|
3. recur with the ``rest'' of the list.
|
|
<P>
|
|
</b></h4></TT></PRE>
|
|
</BLOCKQUOTE>
|
|
<P>
|
|
<BLOCKQUOTE>
|
|
<PRE><TT> <H4><b>RULE OF THUMB 2:
|
|
<P>
|
|
If a function builds a list using ``cons,'' return () at the
|
|
<P>
|
|
terminating line.
|
|
<P>
|
|
</b></h4></TT></PRE>
|
|
</BLOCKQUOTE>
|
|
<P>
|
|
<BLOCKQUOTE>
|
|
<PRE><TT> <H4><b>Example 1:
|
|
<P>
|
|
Write a function, ``remove,'' which takes a list and an element, and
|
|
<P>
|
|
returns the original list with the first occurrence of the element
|
|
<P>
|
|
removed.
|
|
<P>
|
|
</b></h4></TT></PRE>
|
|
</BLOCKQUOTE>
|
|
To solve this problem we will have to look at each of the elements of
|
|
the given list one by one, checking if it is the element to be
|
|
removed. We know that we can stop searching if we
|
|
<DL COMPACT><DT>(1)
|
|
<DD> have reached the end of the list without finding the
|
|
element to be removed, or
|
|
<DT>(2)
|
|
<DD> have found the element to be removed (we can stop, since
|
|
we are only interested in its first occurrence).
|
|
<P>
|
|
</DL>
|
|
Let's try to apply Rule of Thumb 1.
|
|
<DL COMPACT><DT>(1)
|
|
<DD> From the rule we know that at each step we want to recur with the
|
|
``rest'' of the list. Thus, at each recursive call the list will
|
|
get shorter by one element. We must stop when the list becomes
|
|
(). We can use the predicate ``null'' to check for this condition.
|
|
<P>
|
|
<DT>(2)
|
|
<DD> The second part states that we should try to use the first element
|
|
of the list. Before each recursive call we want to check if the
|
|
first element of the list equals the given element. We can use
|
|
the predicate ``equal'' to test for equality.
|
|
<P>
|
|
<DT>(3)
|
|
<DD> We must remember that the function ``remove'' returns the original
|
|
list with the first occurrence of the given element removed. When
|
|
we recur with the ``rest'' of the list, it is important to preserve
|
|
the elements that do not match the given element. Thus, in the
|
|
third part, we should use ``cons'' to save these elements.
|
|
<P>
|
|
</DL>
|
|
Note that we are building a list using ``cons,'' specifically a list of
|
|
elements excluding the element to be removed. Using Rule of Thumb 2,
|
|
we know that in such a case we should return () at the terminating
|
|
line. Thus, if the test for ``null'' returns true, our function will
|
|
return ().
|
|
<P>
|
|
The following solution clearly shows the three parts of Rule of Thumb
|
|
1 and also illustrates the use of Rule of Thumb 2:
|
|
<BLOCKQUOTE>
|
|
<PRE> (defun remove (lst elt)
|
|
(cond ((null lst) nil)
|
|
((equal (first lst) elt) (rest lst))
|
|
(t (cons (first lst)
|
|
(remove (rest lst) elt)))))
|
|
</PRE>
|
|
</BLOCKQUOTE>
|
|
The following notation gives an idea of the execution of ``remove'':
|
|
<BLOCKQUOTE>
|
|
<PRE>(remove '(a 1 c 2 c 7) 'c)
|
|
= (cons 'a (remove '(1 c 2 c 7) 'c))
|
|
= (cons 'a (cons '1 (remove '(c 2 c 7) 'c)))
|
|
= (cons 'a (cons '1 '(2 c 7)))
|
|
= (cons 'a '(1 2 c 7))
|
|
= '(a 1 2 c 7)
|
|
|
|
(remove '(a (1 q) 2) 'q)
|
|
= (cons 'a (remove '((1 q) 2) 'q))
|
|
= (cons 'a (cons '(1 q) (remove '(2) 'q)))
|
|
= (cons 'a (cons '(1 q) (cons 2 (remove '() 'q))))
|
|
= (cons 'a (cons '(1 q) (cons 2 '())))
|
|
= (cons 'a (cons '(1 q) '(2)))
|
|
= (cons 'a '((1 q) 2))
|
|
= '(a (1 q) 2)
|
|
</PRE>
|
|
</BLOCKQUOTE>
|
|
Note, Rule of Thumb 1 provides a general framework within which to
|
|
think about recursion. In different examples, the importance and
|
|
length of the three components may differ. In the following example
|
|
the second part of the rule (using the first element of the list)
|
|
comes into play only implicitly.
|
|
<P>
|
|
<BLOCKQUOTE>
|
|
<PRE><TT> <H4><b>Example 2:
|
|
<P>
|
|
Write a function, ``length,'' which takes a list and returns a count of
|
|
<P>
|
|
all the top level elements in the list.
|
|
<P>
|
|
</b></h4></TT></PRE>
|
|
</BLOCKQUOTE>
|
|
|
|
<div style="border: 1px solid red; background: #ffffdd; margin: 10px; text-align: center"><b>NOTE:</b> This example illustrates that you are allowed to redefine the 'length' function that is built into Lisp. Programmer beware!!</div>
|
|
|
|
|
|
|
|
The solution is:
|
|
<BLOCKQUOTE>
|
|
<PRE> (defun length (lst)
|
|
(cond ((null lst) 0)
|
|
(t (+ 1 (length (rest lst))))))
|
|
</PRE>
|
|
</BLOCKQUOTE>
|
|
|
|
We can identify the three components mentioned in Rule of Thumb 1:
|
|
<DL COMPACT><DT>(1)
|
|
<DD> We still use ``null'' to test for termination, but, since now we
|
|
want to return a count of top level elements, when we reach the
|
|
end of the list we return 0 (the length of a null list).
|
|
<DT>(2)
|
|
<DD> We only use the first element implicitly; we account for its
|
|
presence by adding a one to the value returned by the recursive
|
|
call.
|
|
<DT>(3)
|
|
<DD> We do recur with the ``rest'' of the given list. Although we
|
|
do not explicitly use <code>(first lst)</code>, the first element of the list
|
|
is not forgotten; by adding a one to the result of the recursive
|
|
call, we keep a track of the top level elements.
|
|
<P>
|
|
</DL>
|
|
The following notation gives an idea of the execution of ``length'':
|
|
<BLOCKQUOTE>
|
|
<PRE>(length '(a (2 q) 64))
|
|
= (+ 1 (length '((2 q) 64)))
|
|
= (+ 1 (+ 1 (length '(64))))
|
|
= (+ 1 (+ 1 (+ 1 (length '()))))
|
|
= (+ 1 (+ 1 (+ 1 0)))
|
|
= (+ 1 (+ 1 1))
|
|
= (+ 1 2)
|
|
= 3
|
|
</PRE>
|
|
</BLOCKQUOTE>
|
|
</H4></b></b></b></b></b></H4></b></b></b></H4></b></H4></b><BR> <HR>
|
|
<A HREF="node44.html"><IMG ALIGN=BOTTOM ALT="next" SRC="next_motif.gif"></A>
|
|
<A HREF="node41.html"><IMG ALIGN=BOTTOM ALT="up" SRC="up_motif.gif"></A>
|
|
<A HREF="node42.html"><IMG ALIGN=BOTTOM ALT="previous" SRC="previous_motif.gif"></A> <BR>
|
|
<A HREF="lp.html"><B>Contents</B></A>
|
|
<B> Next:</B>
|
|
<A HREF="node44.html"> Recursion on Nested </A>
|
|
<B>Up:</B>
|
|
<A HREF="node41.html"> Programming Techniques</A>
|
|
<B> Previous:</B>
|
|
<A HREF="node42.html"> A Word about </A>
|
|
<BR> <HR> <P>
|
|
<BR> <HR>
|
|
<P>
|
|
<ADDRESS>
|
|
<I>© Colin Allen & Maneesh Dhagat <BR>
|
|
March 2007 </I>
|
|
</ADDRESS>
|
|
</BODY>
|