Find Function Examples
;
; This file contains three solutins to a fund function, which searches a list
; some requested item, and returns its zero-based position in the list (if
; found), or -1 if not.
; (find '(a b c d) 'a) returns 0
; (find '(a b c d) 'b) returns 1
; (find '(a b c d) 'd) returns 3
; (find '(a b c d) 'z) returns -1
; *** Version 1. This uses a recursive case to find the indicated item in the
; tail of the list. The recursive case must add one to the position when
; the item is found (since it was found in a one-step shorter list), but
; avoid that increment when the recursive case indicates the item was not
; found. It does this by using a let to store the result of the recursion,
; then modifies that conditionally.
(define (find lis x)
(cond
((null? lis) (- 0 1))
((equal? x (car lis)) 0)
(#t (let
( (recval (find (cdr lis) x)) )
(if (< recval 0) recval (+ recval 1))
)
)
)
)
; *** Version 2. This is similar to the first version, but uses a helper
; function to conditionally increment the result returned from the
; recursion, so the let is unnecessary. Both versions are similar in that
; the keep the recursion result in a variable: In the first place, it is
; placed in the let variable. In the second, the parameter x of the
; helper function +except-neg.
; Take a number. For negatives, return it; for others increment it.
(define (+except-neg x)
(if (< x 0) x (+ x 1))
)
(define (find lis x)
(cond
((null? lis) (- 0 1))
((equal? x (car lis)) 0)
(#t (+except-neg (find (cdr lis) x)))
)
)
; *** Version 3. This slightly different approach adds a parameter used to
; keep track of the nesting depth (which is also the number of list
; items discarded by the cdr calls) on the way in. This becomes the
; return value and does not need to be incremented in the recursive case.
; This avoids the need for the recursive case to modify the result it
; receives, and to treat -1 differently.
(define (find lis x) (find-r lis x 0))
(define (find-r lis x depth)
(cond
((null? lis) (- 0 1))
((equal? x (car lis)) depth)
(#t (find-r (cdr lis) x (+ depth 1)))
)
)