如何在不删除方案中的元素的情况下遍历列表中的每个元素
How to iterate through every element in list without removing elements in scheme
我的问题是使用 Racket R5RS 语言制作一个简单的加减程序。题目的基本思路是在list中的每个元素前都加上plus/minus符号,判断结果是否是list中的元素之一。以下是我现在拥有的:
(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))))
这段代码可以,但是要求参数中只能有一个列表,其他都是数字。第一次调用该函数时,我的代码中的前两个参数是相同的。第一个是获得总和的那个。第二个是检查总和是否等于列表中的元素之一。这两个列表都是必需的,因为当我得到总和时,第一个列表中的元素被删除。
我的问题是,如何去掉参数中的第二个列表?无论如何我可以在不删除元素的情况下遍历列表(CDR 推荐)?
首先是你的代码部分
(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
中绑定 plus-minus-helper
,或者使用 let
的形式letrec
。通过这些方式,您还可以引用输入的原始参数,因此您不需要另一个参数。
(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))))
我的问题是使用 Racket R5RS 语言制作一个简单的加减程序。题目的基本思路是在list中的每个元素前都加上plus/minus符号,判断结果是否是list中的元素之一。以下是我现在拥有的:
(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))))
这段代码可以,但是要求参数中只能有一个列表,其他都是数字。第一次调用该函数时,我的代码中的前两个参数是相同的。第一个是获得总和的那个。第二个是检查总和是否等于列表中的元素之一。这两个列表都是必需的,因为当我得到总和时,第一个列表中的元素被删除。
我的问题是,如何去掉参数中的第二个列表?无论如何我可以在不删除元素的情况下遍历列表(CDR 推荐)?
首先是你的代码部分
(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
中绑定 plus-minus-helper
,或者使用 let
的形式letrec
。通过这些方式,您还可以引用输入的原始参数,因此您不需要另一个参数。
(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))))