如何迭代列表中的每个元素而不删除scheme中的元素

时间:2016-04-29 01:23:29

标签: list scheme lisp racket r5rs

我的问题是使用Racket R5RS语言制作一个简单的加减程序。该问题的基本思想是在列表中的每个元素前面加上加号/减号,并检查结果是否是列表中的元素之一。以下是我现在所拥有的:

(define plus-minus (lambda (lst l sum)
                (cond
                  ((null? lst)
                   (cond
                     ((null? l) #f)
                     ((= sum (car l)) #t)
                     (else (plus-minus lst (cdr l) sum))))
                  ((plus-minus (cdr lst) l (+ sum (car lst))) #t)
                  ((plus-minus (cdr lst) l (- sum (car lst))) #t)
                  (else #f))))

此代码正常运行,但要求参数中只有一个且只有一个列表,其他所有列表都是数字。首次调用函数时,我的代码中的前两个参数是相同的。第一个是获得总和的人。第二个是检查sum是否等于列表中的一个元素。这两个列表都是必需的,因为当我得到总和时,第一个列表中的元素将被删除 我的问题是,如何摆脱参数中的第二个列表?反正我是否可以在不删除元素的情况下遍历列表(CDR表示)?

1 个答案:

答案 0 :(得分:3)

首先,代码的一部分

(cond
  ((null? l) #f)
  ((= sum (car l)) #t)
  (else (plus-minus lst (cdr l) sum))))

检查sum是否在l。有一个函数已经被称为member,因此您可以用(member sum l)替换整个块,这更干净。

我也想先纠正错误观念。 cdr 从列表中删除元素。列表被定义为空列表,或者一对元素和另一个列表。例如

[1 [2 [3 empty]]]

是一个包含三个元素的列表:123car做的是获取对中的第一个元素。 cdr做的是获取对的第二个元素。什么都没有删除。

要删除其他参数,您可能希望将此函数重命名为另一个函数,例如plus-minus-helper,然后创建plus-minus,然后调用plus-minus-helperplus-minus然后是:

(define (plus-minus lst)
  (plus-minus-helper lst lst 0))

或者,如果您想在一个函数中执行所有操作,还可以使用letrec绑定plus-minus-helper plus-minus,或使用let形式的letrec 1}}。通过这些方法,您还可以参考输入的原始参数,因此您不需要另一个参数。

(define (plus-minus init-lst)
  (let plus-minus-helper ((lst init-lst)
                          (sum 0))
    (cond
      ((null? lst) (member sum init-lst))
      ((plus-minus-helper (cdr lst) (+ sum (car lst))) #t)
      ((plus-minus-helper (cdr lst) (- sum (car lst))) #t)
      (else #f))))