在列表中添加偶数项

时间:2010-12-12 04:06:19

标签: scheme

我想在列表中添加偶数项并使用我编写的以下算法来实现目标。

我得到的错误是:

  

+:期望类型< number>作为第二个参数,给出:#< void&gt ;;其他论点是:4

代码:

(define (mylength alist cnt)
  (if (null? alist)
  0

  (if (= (modulo cnt 2) 0)(+ (car alist) (mylength (cdr alist) (+ cnt 1)))))
  (if (= (modulo cnt 2) 1)(mylength (cdr alist) (+ cnt 1))))

你能告诉我吗? i)错误 ii)算法的逻辑

谢谢!

2 个答案:

答案 0 :(得分:2)

首先,正确缩进代码:

(define (mylength alist cnt)
  (if (null? alist)                                       ; 
    0                                                     ; this section is wasted because
    (if (= (modulo cnt 2) 0)                              ; it's not the last expression
      (+ (car alist) (mylength (cdr alist) (+ cnt 1)))))  ;
  (if (= (modulo cnt 2) 1)               ; this if is the last expression, but 
    (mylength (cdr alist) (+ cnt 1))))   ; if it's false you get #<void>

你不应该有if个没有true和false分支的表达式。你必须记住,这不是C,任何不是最后一个表达式的东西都会被运行然后扔掉。

将最后两个if语句合并为一个if语句:

(define (mylength alist cnt)
  (if (null? alist)
    0
    (if (= (modulo cnt 2) 0)
      (+ (car alist) (mylength (cdr alist) (+ cnt 1)))
      (mylength (cdr alist) (+ cnt 1)))))

编辑:当我写下“任何不是最后一个表达式的东西都会被运行然后扔掉”时,我的意思是:

(begin
  (+ 2 2)
  (+ 4 1)
  (+ 1 0)
  (+ 1 1)) => 2

(let ((x 5))
  (add1 x)
  (+ x 2)
  (* x 2)) => 10

((lambda ()
   (if #t 3)
   (if #f 0 4)
   (if #t 2))) => 2

答案 1 :(得分:0)

另一个答案是完全正确的,但你的界面不是很方便。这是一种带尾递归的更常见的形式。

; Assumes given a list of numbers. Returns sum of even indices.
(define (mylength alist)
  (let helper ((alist alist) (acc 0))
    (cond
      ((null? alist) acc)
      ((null? (cdr alist)) (+ acc (car alist)))
      (else (helper (cddr alist) (+ acc (car alist)))))))