我的问题是使用 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 推荐)?
最佳答案
首先,你的代码部分
(cond
((null? l) #f)
((= sum (car l)) #t)
(else (plus-minus lst (cdr l) sum))))
是检查sum
是否在l
中。有一个名为 member
的函数可以执行此操作,因此您可以用 (member sum l)
替换整个 block ,这样更干净。
我也想先纠正一个误解。 cdr
不会从列表中删除元素。列表被定义为空列表,或者一个元素和另一个列表的对。例如
[1 [2 [3 empty]]]
是一个包含三个元素的列表:1
、2
和 3
。 car
的作用是获取该对的第一个元素。 cdr
的作用是获取该对的第二个元素。没有删除任何内容。
要摆脱额外的参数,您可能需要将此函数重命名为另一个函数,例如 plus-minus-helper
,并创建 plus-minus
,然后调用加减助手
。 加减
则为:
(define (plus-minus lst)
(plus-minus-helper lst lst 0))
或者,如果您想在一个函数中完成所有操作,您也可以使用 letrec
在 plus-minus
内绑定(bind) plus-minus-helper
code>,或使用 letrec
的 let
形式。通过这些方式,您还可以引用输入的原始参数,因此不需要另一个参数。
(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))))
关于list - 如何迭代列表中的每个元素而不删除方案中的元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36928054/