爲什麼訴諸於只能在特定情況下使用的解決方案,並在其他情況下產生錯誤的結果?命令式編程是如此1980 ... 80年代很酷,我知道,但也有點有限, 不是?
請試着根據的關係,可以在所有方向使用!
下面是一個使用if_/3
對於一般性的解決方案:
no_consecutive_duplicates([], []).
no_consecutive_duplicates([L|Ls0], Ls) :-
no_dups(Ls0, L, Ls).
no_dups([], E, [E]).
no_dups([L|Ls0], E, Ls) :-
if_(L=E, Ls=Ls1, Ls=[E|Ls1]),
no_dups(Ls0, L, Ls1).
它的工作原理也是最常見的情況:
?- no_consecutive_duplicates(Ls0, Ls).
Ls = Ls0, Ls0 = []
Ls = Ls0, Ls0 = [_G501] ;
Ls = [_G501],
Ls0 = [_G501, _G501] ;
Ls = [_G501],
Ls0 = [_G501, _G501, _G501] .
對於公平枚舉,使用例如:
?- length(Ls0, _), no_consecutive_duplicates(Ls0, Ls).
Ls = Ls0, Ls0 = [] ;
Ls = Ls0, Ls0 = [_G501] ;
Ls = [_G501],
Ls0 = [_G501, _G501] ;
Ls = [_G775, _G775],
Ls0 = [_G787, _G775],
dif(_G775, _G787) .
注意使用prolog-dif以聲明狀態說明兩個詞是 不同。
順便說一下, 「正常」 的情況下,工作太:
?- no_consecutive_duplicates([a,b,c], Ls).
Ls = [a,b,c].
?- no_consecutive_duplicates([a,a,b,c,c], Ls).
Ls = [a,b,c].
注意,這兩個查詢成功確定性。
這不是很好,我們可以概括這一點,並檢查也稍微複雜的情況?
?- no_consecutive_duplicates([a,b,X], Ls).
Ls = [a, b],
X = b ;
Ls = [a, b, X],
dif(X, b).
保持純粹的人!
請參閱我的編輯中的說明。 – rnso
您的解決方案缺少的一個子句是第一個參數是一個元素列表的情況。您的基本案例處理空列表,並且遞歸大小寫處理至少兩個元素。所以它會在一個元素的列表上失敗。另外,你的謂詞總是減少到第二個參數的空列表,而不是收集結果列表。 – lurker
添加removeDups([H | []],[H | []])。沒有幫助。對於第二個方面,如果我添加removeDups([H1,H2 | T],L),它會變成無限循環。 – rnso