我的问题是使用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表示)?
答案 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]]]
是一个包含三个元素的列表:1
,2
和3
。 car
做的是获取对中的第一个元素。 cdr
做的是获取对的第二个元素。什么都没有删除。
要删除其他参数,您可能希望将此函数重命名为另一个函数,例如plus-minus-helper
,然后创建plus-minus
,然后调用plus-minus-helper
。 plus-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))))