2015-01-05 78 views
3

我正在嘗試編寫將從列表列表中的所有列表中刪除所有標點符號(。,!?等)的序言代碼。這是我到目前爲止:在列表中刪除標點符號的問題

delete_punctuation(_,[],_). 
delete_punctuation(Character,[List|Tail],Resultlist) :- 
    delete(List,Character,NewList), 
    delete_punctuation(Character,Tail,[NewList|Resultlist]). 

而'字符'將爲33!或46。等等,因爲我只會在字符代碼列表中使用它。 (我知道,該功能實際上對,我想從列表中刪除過其他元素的工作。)

問時,我收到了效果:

delete_punctuation(33,[[45,33,6],[4,55,33]],X). 

只是

|: true. 

不過,我希望它是:

|: X = [[45,6],[4,55]]. 

我需要做什麼來改善?

+0

你的基本情況看起來不正確。 'delete_punctuation(_,[],_)'表示你不關心從空列表中刪除標點符號的結果是什麼。但我會提出你非常關心結果是什麼。 :)然後,您的主要子句將有一些問題,因爲您確實希望'Resultlist'是'[NewList | Rest]',其中'Rest'是您的遞歸'delete_punctuation'的結果。 – lurker

+0

在任何情況下,您的問題均未指定。你對delete_punctuation(33,[[33,33]],X)''有什麼期望?應該刪除還是隻有一個?還有什麼,沒有? – false

+0

@lurker:所以我的基本情況應該是'delete_punctuation(_,[],[])。'也許我應該添加另外一個例子,比如'delete_punctuation(Character,[[Character | T1] | T2],Resultlist): - delete_punctuation(Character,[T1 | T2],Resultlist)'? –

回答

1

對於這個問題,我想通過單獨解決的兩個子問題,即解決它:

  • 過濾器/排除單個列表中的字符代碼;
  • 將上述解決方案應用於字符代碼列表的列表。

爲此,我想接近它是這樣的:

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. 
+0

謝謝!有了這個,並在我的帖子下的所有評論的幫助下,我得到了比我希望的更多的答案。 –