2011-06-17 85 views
4
flatten([A|B],R):- (islist(A)->(flatten(A,R1),R=R1);(write(A),append([A],R1,R))), flatten(B,R1). 
    flatten(X,X). 
    islist([_|_]). 

這是我寫的代碼,但我有奇怪的問題..Prolog的扁平化列表

我得到

257 ?- flatten([1,[],2,[3],[3,[3,5]]],R). 
1[]23335335 
R = [1, [], 2, [3], [3, [3, 5]]] . 

雖然從寫沒有列出他們被追加爲列表中的號碼:S ...

+0

請改善您的代碼的格式。事實上,這是不可能讀的。 – Kaarel 2011-06-17 12:17:26

+1

+1。不知道爲什麼有人給這個問題-1。有示例代碼和輸出表明不需要的行爲。 – z5h 2011-06-20 15:37:34

回答

7

,我們在您的定義一些錯誤壓扁/ 2:

你第一句話會失敗是因爲如果A是一個列表,它將首先用R實例化R1,然後嘗試用平坦化(B,R1)再次統​​一它。

變平(X,X)。 - >這個條款將'原樣'留在列表中,沒有任何壓縮。

檢查這個其他實施:

flatten(List, Flattened):- 
    flatten(List, [], Flattened). 

flatten([], Flattened, Flattened). 
flatten([Item|Tail], L, Flattened):- 
    flatten(Item, L1, Flattened), 
    flatten(Tail, L, L1). 
flatten(Item, Flattened, [Item|Flattened]):- 
    \+ is_list(Item). 

這裏我們使用兩個謂詞:壓平/ 2和壓平/ 3。 'work'將在flatten/3中完成,其中第二個參數將保存中間平展列表。

第一子句是基本情形:當我們到達空列表,我們這樣做我們實例與中間扁平列表中的第三個參數。

第二個子句處理遞歸。它將列表中的第一個項目弄平(無論是項目還是子列表),並繼續處理輸入列表的其餘部分。

最後一項是非列表項的「基本情況」。它預先考慮在中間壓平列表的開頭的項目,但它只做這是在不列爲該案件的第二子句中的照顧項目。

+1

感謝你的explanation.i曾1天序言​​經驗..這是一個有點怪異:) – GorillaApe 2011-06-20 16:04:18