开发者

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)))

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜