1
(define key
  (lambda (w)
    (reverse w)
    (if (null? w)
     0
    (let ((k 33))
         (+ (* (ctv(car w)) k) (key (cdr w)))
))))

输出与此相同的内容:

(define key
  (lambda (w)
    (if (null? w)
     0
    (let ((k 33))
         (+ (* (ctv(car w)) k) (key (cdr w)))
))))

为什么我的单词没有反转然后计算?

输入:(键'(xyz))

输出:2475(两种方法)

我不明白为什么会这样。有人请帮我看看为什么会这样。

4

3 回答 3

3

正如已经指出的那样,该reverse过程返回一个列表,它不会就地修改作为参数传递的列表(这发生在所有修改列表的过程中,小心它)。这就是(reverse w)代码中的行没有任何效果的原因:它肯定会返回一个新的反向列表,但您忽略了返回的值!

要使用反向列表,您必须将其存储或传递到某个地方,一个好主意是将其保存在let表单内定义的局部变量中,并从那时起引用该变量。这就是@michaelb958 的建议:

(define key
  (lambda (w)
    (let ((w (reverse w)))
      (if (null? w)
          0
          (let ((k 33))
            (+ (* (ctv (car w)) k) (key (cdr w))))))))

但是,请注意,每次在遍历列表时调用递归时,上述内容都会反转w列表,我认为这不是您想要的!如果您只需要反转列表一次,请在调用之前调用,并且不要在内部调用:reverse keyreverse key

(key (reverse '(x y z)))
于 2013-04-17T01:58:49.577 回答
2

reverse只返回反转的列表,而不是将其反转到位。你需要

(let ((w (reverse w)))
  ...)

得到你想要的效果。

于 2013-04-17T01:26:15.240 回答
1

由于,正如其他人所指出的那样,reverse不会原地反转,因此您的代码应修改为:

(define key
  (lambda (w)
    (set! w (reverse w))                ; CHANGE IS HERE
    (if (null? w)
         0
         (let ((k 33))
           (+ (* (ctv (car w)) k)
              (key (cdr w)))))))

请注意,您正在递归调用key,因此您将一次又一次地来回反转。

于 2013-04-17T02:20:31.130 回答