2016-04-29 48 views
2

我的问题是使用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)))) 

此代码工作,但它是必需的,应该有一个且只有一个在参数列表中且其他所有的数字。我的代码中的前两个参数在首次调用函数时是相同的。第一个是获得总和的人。第二个是检查和是否等于列表中的元素之一。这两个列表都是必需的,因为当我得到总和时,第一个列表中的元素被删除。
我的问题是,如何摆脱参数中的第二个列表?无论如何,我可以遍历列表而不删除元素(CDR表示)?

回答

3

首先,你的代码

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

的部分是检查suml与否。有一个功能可以这么做,叫做member,所以你可以用更简洁的(member sum l)来代替整个块。

我想先纠正一种误解。 cdr确实不是从列表中删除元素。列表被定义为空列表,或者一对元素和另一个列表。例如

[1 [2 [3 empty]]] 

是具有三个元素的列表:12,和3car做的是取对的第一个元素。 cdr所做的是获取该对中的第二个元素。没有东西被删除。

要摆脱其他参数,您可能需要将此函数重命名为另一个函数,如plus-minus-helper,然后创建plus-minus,然后调用plus-minus-helperplus-minus则是:

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

另外,如果你想在一个函数做的一切,你也可以使用letrec绑定plus-minus-helperplus-minus,或使用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)))) 
相关问题