2010-10-23 116 views
0

繼承人片段:遞歸追加列表

translate("a", "4"). 
translate("m", "/\\/\\"). 

tol33t([], []). 
tol33t([Upper|UpperTail], [Lower|LowerTail]) :- 
    translate([Upper], [Lower]), 
    tol33t(UpperTail, LowerTail). 

基本上是我想要做的是查找表中的一個字母,然後拿到這封信,並把它添加到新的列表。

我有什麼作品,如果它的一個字符,但我不知道如何追加舊的字符的新列表。

輸入示例:

l33t(「was」,L)。 它會通過這樣的: l33t([119,97,115],L)。

現在應該回來爲: [92,47,92,47] ++ [52] ++ [53]或[92,47,92,47,52,53]

問題是我不知道如何像那樣追加它。

回答

3

考慮這些修改tol33t/2

tol33t([], []). 
tol33t([Code|Codes], Remainder) :- 
    translate([Code], Translation), !, 
    tol33t(Codes, Rest), 
    append(Translation, Rest, Remainder). 
tol33t([Code|Codes], [Code|Remainder]) :- 
    tol33t(Codes, Remainder). 

第一子句是基本情形。

第二個子句會成功當且僅當是通過translate/2當前Code一個翻譯,因爲任意長度的字符的列表(Translation - 注意你有[Lower]代替,後者禁區結果長度爲1只的列表)。檢查代碼轉換後的剪切(!)承諾會遞歸查找解決方案的Rest,然後將Translation附加到前面,作爲Remainder返回。

如果在第二個子句中當前沒有翻譯Code(即translate/2),則執行第三個子句。在這種情況下,Code沒有翻譯意味着我們只是按原樣返回並計算其餘部分。

編輯:

如果不削減(!),第二和第三子句可以組合成爲:

tol33t([Code|Codes], Remainder) :- 
    tol33t(Codes, Rest), 
    (translate([Code], Translation) ->    
     append(Translation, Rest, Remainder) 
    ; Remainder = [Code|Rest] 
    ). 

這(未優化)版本檢查,在每Code在字符列表中,如果有一個translate/2,那麼;如果是這樣,Translation被追加到Rest,否則Code通過不變。請注意,這與上面的實現具有相同的語義,因爲如果前導到->translate/2)成功,則解決方案承諾(即,模擬切割!)。請注意,這兩種實現方式的削減是絕對必要的;沒有它,程序將回溯到找到解決方案,其中Code綁定不存在適用translate/2子句的情況下進行翻譯。

+0

我已經做了一些非常接近你在那裏的東西。問題是我不能使用切割,所以這就是爲什麼我一直卡住 – Matt 2010-10-23 13:58:12

+0

其實這應該是沒有檢查,以確定翻譯是否存在。謝謝! – Matt 2010-10-23 14:08:23

+0

啊哈...如果你不能使用cut,你可以用' - >'代替。我將在編輯中添加代碼。 – sharky 2010-10-24 02:21:21