2016-04-29 41 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)))) 
相關問題