2017-04-17 94 views
0

我是Scheme新手,功能編程所以請溫和。 我想實現的功能是獲得一個列表和一個支點,並返回一個包含以下2所列出的清單:Scheme:按元素排序元素

一個用於爲小於或等於樞軸所有元素,

和一個對於所有比樞軸更大的元素。

所以我寫了下面的代碼(編輯(&工作)CODE - 問題解決了):

define helper (lambda (lst pivot) 
      (define lst1 null) 
      (define lst2 null) 
      (define my-split (lambda (lst pivot lst1 lst2) 
           (if (null? lst) 
            (list lst1 lst2) 
            (if (<= (car lst) pivot) 
             (my-split (cdr lst) pivot (cons (car lst) lst1) lst2)           
             (my-split (cdr lst) pivot lst1 (cons (car lst) lst2))))))         
       (my-split lst pivot lst1 lst2))) 

我目前的問題是lst1lst2null在運行結束,所以我想這個問題與行(cons (car lst) lst1) & (cons (car lst) lst2)))

我在網上看到了一些使用一些我不允許使用的複雜命令的實現(是的,它是作業)。

請提供修復我的代碼而不是提供自己的代碼的方法。

謝謝

回答

1

您正確地確定了兩條線是主要問題。 cons只是生成並返回一個新列表,而您試圖變異變量lst1lst2。正確的方法是(set! lst1 (cons (car lst) lst1))(set! lst2 (cons (car lst) lst2))。但請記住,良好的函數式編程風格可以避免突變。在這種情況下,做一個好的方法是在主列表中重複傳遞兩個子列表作爲參數,然後在達到最後時返回它們。

+0

謝謝你的回答,但正如我所提到的,我不允許使用'set!',我試着給輸入參數添加'lst1'&'lst2',然後將它們作爲參數傳遞,但結果是相同的看我的編輯)。你能提供你提供的代碼樣本嗎? – Noam

+1

@Noam你快到了。將最後一行的'(list lst1 lst2)'移到第一個'if'表達式的第一部分(替換'null')。 –

+0

謝謝,已解決。 – Noam

1

就像Java中的一個表達式str.concat("hey")不會改變什麼str(cons 1 lst1)不會改變什麼lst1是。它只是返回一個新值。你的大部分函數都由死代碼組成,如果你真的想學習函數式編程,那麼改變綁定和對象是不受限制的。

你需要做這樣的事情:

(define (count-odds lst) 
    (define (helper lst odds) 
    (cond ((null? lst) 
      odds) 
      ((odd? (car lst)) 
      (helper (cdr lst) (+ 1 odds))) 
      (else 
      (helper (cdr lst) odds))))  
    (helper lst 0)) 

(count-odds '(1 2 3)) 
; ==> 2 

我們從來沒有改變odds,我們剛剛更新的內容發送到下一個遞歸。由於Scheme有尾部調用消除,這就像更新while循環中的變量而沒有實際的變化。

+0

謝謝你解釋,我理解你的例子,但我不知道如何將它應用於我的問題,我已經編輯我的代碼,試圖做你說的,但結果是一樣的。有任何想法嗎? – Noam

+0

當'split-at'返回'lst1'並且'lst2'再次以空值結束時。因爲你想從'split-at'得到結果,所以你想刪除它。當你敲'lst'的結尾而不是返回null時,你也可能想用'lst1'和'lst2'做些事情。在過程中定義的'lst1'和'lst2'也有**參數。他們恰好有相同的名字。 – Sylwester