對於這個問題,我想通過單獨解決的兩個子問題,即解決它:
- 過濾器/排除單個列表中的字符代碼;
- 將上述解決方案應用於字符代碼列表的列表。
爲此,我想接近它是這樣的:
exclude2(_, [], []).
exclude2(Code, [Code|Xs], Ys) :-
!, % ignore the next clause if codes match
exclude2(Code, Xs, Ys).
exclude2(Code, [X|Xs], [X|Ys]) :-
% else, Code != X here
exclude2(Code, Xs, Ys).
注意到有一些像SWI-Prolog provide exclude/3
as a built-in,所以你可能實際上並不需要自己定義。現在
,上述斷言適用於列表的列表:
delete_punctuation(_, [], []).
delete_punctuation(Code, [L|Ls], [NewL|NewLs]) :-
exclude(Code, L, NewL),
delete_punctuation(Code, Ls, NewLs).
然而,再次,取決於實施,內置樣maplist/3
可以用來達到同樣的效果,而不必定義一個新的謂詞:
?- maplist(exclude2(33), [[45,33,6],[4,55,33]], X).
X = [[45, 6], [4, 55]] ;
false.
nb如果你想使用所有SWI內置插件,exclude/3
要求測試是一個目標,就像這樣:
?- maplist(exclude(==(33)), [[45,33,6],[4,55,33]], X).
X = [[45, 6], [4, 55]] ;
false.
對於一個更通用的方法,你甚至可以添加你所要排除的代碼(如任何和所有的標點字符代碼)的列表作爲過濾器的使用方法:
excludeAll(_, [], []).
excludeAll(Codes, [Code|Xs], Ys) :-
member(Code, Codes),
!,
excludeAll(Codes, Xs, Ys).
excludeAll(Codes, [X|Xs], [X|Ys]) :-
excludeAll(Codes, Xs, Ys).
然後你就可以添加一個清單,所有的代碼刪除:
?- maplist(excludeAll([33,63]), [[45,33,6],[4,55,33,63]], X).
X = [[45, 6], [4, 55]] ;
false.
你的基本情況看起來不正確。 'delete_punctuation(_,[],_)'表示你不關心從空列表中刪除標點符號的結果是什麼。但我會提出你非常關心結果是什麼。 :)然後,您的主要子句將有一些問題,因爲您確實希望'Resultlist'是'[NewList | Rest]',其中'Rest'是您的遞歸'delete_punctuation'的結果。 – lurker
在任何情況下,您的問題均未指定。你對delete_punctuation(33,[[33,33]],X)''有什麼期望?應該刪除還是隻有一個?還有什麼,沒有? – false
@lurker:所以我的基本情況應該是'delete_punctuation(_,[],[])。'也許我應該添加另外一個例子,比如'delete_punctuation(Character,[[Character | T1] | T2],Resultlist): - delete_punctuation(Character,[T1 | T2],Resultlist)'? –