How to traverse into inner list in Scheme?
I'm writing a procedure which counts the number of zeros in a given list. This list could have another nested list. The algorithm that I came up with was very straightforward:
- If the current list is null, return 0
- If the current list is another list, call subprogram to count zeros in this list.
- Else keep traversing the parent list and count zeros if any.
However, I always get the error says,
=: expects type <number> as 2nd argument, given: quote; other arguments were: 0
and I have no idea how this could be. Any idea?
My attempt was,
(define (helper lst)
(cond 开发者_StackOverflow((null? lst) 0)
((= 0 (car lst)) (+ 1 (helper (cdr lst))))
(else (+ 0 (helper (cdr lst))))))
(define (count-zeroes lst)
(cond
((null? lst) 0)
(else
(if (list? (car lst))
(+ (helper (car lst)) (count-zeroes (cdr lst)))
(if (= 0 (car lst))
(+ 1 (count-zeroes (cdr lst)))
(+ 0 (count-zeroes (cdr lst))))))))
(define ll '(0 1 2 0 '(1 0 0)))
(count-zeroes ll)
Thanks,
You don't need a helper method like that, per se. The count-zeroes method can call itself recursively on the car if the car is a list.
I'd go with something like this instead
(define (count-zeroes lst)
(cond
((null? lst) 0)
((list? (car lst)) (+ (count-zeroes (car lst)) (count-zeroes (cdr lst))))
((equal? (car lst) 0) (+ 1 (count-zeroes (cdr lst))))
(else (count-zeroes (cdr lst)))
)
)
It's been a while since I practiced scheme but:
A) I don't think cddr
is the correct procedure in (+ (helper (car lst)) (count-zeroes (cddr lst)))
- it should just be cdr.
B) You don't need a second helper function- you should be able to call (count-zeroes car lst)
just fine, because at that point you're passing a list that will be split up the same way its parent was.
So the line in contention would be (+ (count-zeroes (car lst)) (count-zeroes (cdr lst)))
精彩评论