2013-01-15 106 views
2

我在SML中有兩個列表,可以說列表A [(a,b,c),(d,e,f)]和列表B [b,e]。我想算在B中每個三元的第二個元素匹配A.每個項目的多少發生輸出應該是2,由於be各A.在SML中對多個列表進行迭代

這是到目前爲止我的代碼發生一次,但當我從B中的一個元素移動到另一個元素時,我的計數器始終設置爲0.我知道在Java中,這只是一個簡單的double for循環。

fun number_in_months (d : (int * int * int) list, m : (int) list) = 
    if null m then 0 
    else if null d then number_in_months(d, tl m) 
    else if (#2(hd d)) = (hd m) then 1 + number_in_months (tl d, m) 
    else number_in_months(tl d, m) 
+0

您真的不想使用模式匹配,而是使用'null'對空列表進行測試。這樣你就不需要明確地將列表的首尾相連,因爲你已經將它們模式匹配到了例如(x :: xs)和(y :: ys) –

回答

2

正如你所提到的,它將是任何命令式編程語言中的嵌套/雙重循環。你實際上錯過的是第二個循環。

你的「內部」環路經過的d所有元素,並在這樣做,你的「外」循環試圖彈出的m頂部的元素,一切重新開始,從該行代碼的看到:

else if null d then number_in_months(d, tl m) 

但是你可以看到,你剛纔測試列表d是空的,你提供這個(完全一樣的列表)到您的遞歸調用上的m尾部,然後將落在此相同的情況下每個連續呼叫,直到m也是空的,你返回0.

因此,您缺少的是「保留副本」的原始輸入列表m。這可以通過各種方式來完成,但是內部(輔助)功能是正常的最廣泛的一種,它甚至「看起來」像一個嵌套循環

fun number_in_months (d, m) = 
    let 
     fun nim' ([], y::ys) = nim (d, ys)     (* 1 *) 
     | nim' (_, []) = 0        (* 2 *) 
     | nim' ((_, x2, _) :: xs, yss as (y::ys)) = ... (* 3 *) 
    in 
     nim'(d, m) 
    end 

使用模式匹配上面的代碼變得更簡單和更小的誤差俯臥。在情況1中,「內部」循環已經通過d中的所有元素,因此從外部函數使用d的遞歸調用在任何時候都不會改變。在情況2中,「外部」循環已經歷了m的所有元素,並且我們返回0(加法的中性元素)。在情況3中,我們做了實際的工作。這裏使用了模式匹配,因此我們不需要強制實現參數的類型,也不需要提取三元組的第二個元素,我們已經將它放在變量x2中。所需要做的就是做計算並用xsyss進行遞歸調用。

這樣做時,內部(輔助函數)函數使用原始輸入列表d的「複製」並逐步遍歷其元素(可能會修改它),但我們總是獲得對原始輸入列表的引用,如果需要,我們可以使用它。

+0

感謝您的解釋,您指出的錯誤非常重要,我終於得到了我想要的。 – fanbondi

5

該代碼不會在遞歸調用之間累積值。也可能有其他邏輯錯誤。

使用遞歸和函數累加值是一種常見模式,您可以閱讀更多關於here的內容。其實質是使用headtail解構列表,直到列表爲空,並在每次調用時累積一些值。下面的sum函數是一個簡單的例子來說明這一點。當be被發現在list A中時,這可以適用於您的示例以積累acc

fun sum(numbers: (int) list) = 
    let fun sumR(numbers: (int) list, acc: int) = 
    if null numbers 
    then acc 
    else 
     sumR(tl numbers, hd numbers + acc) 
    in 
    sumR(numbers, 0) 
    end 

運行在[1,2,3]給出:

val sum = fn : int list -> int 
- sum([1,2,3]); 
val it = 6 : int 

注意我用,因爲這這個答案故意含糊是關於Coursera功課的編程語言類的問題。

+0

感謝您的回答,如果我在 [(1,2,3)(2,2,3)(4,2,3)]上運行代碼,[2,4]我得到了答案6,這是中間2的總和。所以它的累計問題是它應該進一步繼續,並在第一個列表的中間元素中檢查4,如果發現4,則應該更新爲7. – fanbondi

+1

對於'number_in_months'輸入的答案[[(1 ,2,3),(2,2,3),(4,2,3)],[2,4]'應該是3,因爲每個'日期'具有'2'作爲月份,'2'處於'月'的列表 – Brian

+0

是的,你是對的,它應該是3不是6,那是我的錯誤。 – fanbondi