Prolog:删除列表中的所有空格

时间:2016-04-24 14:15:27

标签: recursion prolog

我有这样的列表列表:

[[q, ,w, ,e, ,r, ,t, ,z],[a, ,s, ,d, ,f, ,g, ,h],[y, ,x, ,c, ,v, ,b, ,n]]

我需要删除除最后一个列表之外的所有空格。 所以我想:

[[q,w,e,r,t,z],[a,s,d,f,g,h],[y, ,x, ,c, ,v, ,b, ,n]]

我试过了:

deleteAll([_|[]],[]).
deleteAll([Head|Tail],L) :-
  deleteAll(Tail,_),
  subtract(Head,[ ],L).

但它不起作用。我正在接受:

[q, ,w, ,e, ,r, ,t, ,z]

所以看起来即使减去也没有将[]作为空格。 我怎样才能做到这一点?

4 个答案:

答案 0 :(得分:3)

:- set_prolog_flag(double_quotes, chars).
:- use_module(library(double_quotes)).

spdels([], []).
spdels([Cs], [Cs]).
spdels([Cs|Css], [Ds|Dss]) :-
   Css = [_|_],
   Dss = [_|_],
   text_nospaces(Cs, Ds),
   spdels(Css, Dss).

text_nospaces([], []).
text_nospaces([C|Cs], Ds0) :-
   if_(C = ' ', Ds0 = Ds1, Ds0 = [C|Ds1] ),
   text_nospaces(Cs, Ds1).


text_nospaces_bis(Cs, Ds) :-
   tfilter(dif(' '), Cs, Ds).

使用if_/3tfilter/3

| ?- spdels(["a b c","d e","f g"], Cs).
Cs = ["abc","de","f g"] ? ;
no

答案 1 :(得分:3)

为什么不将“递归部分”委托给Prolog库谓词?

基于tfilter/3dif/3定义spaces_gone/2,如下所示:

:- use_module(library(lists), [same_length/2, reverse/2, maplist/3]).

spaces_gone([], []).
spaces_gone([A|As], [D|Ds]) :-
   same_length(As, Ds),
   reverse([A|As], [Last|Bs]),
   maplist(tfilter(dif(' ')), Bs, Cs),
   reverse([Last|Cs], [D|Ds]).

使用SICStus Prolog 4.3.2的示例查询:

| ?- set_prolog_flag(double_quotes, chars),
     use_module(library(double_quotes)).
% ...
yes

| ?- spaces_gone(["a b c","d e","f g"], Css).
Css = ["abc","de","f g"] ? ;
no

答案 2 :(得分:2)

由于@false已经指出[ ]不是空格而是空列表。此外,您的谓词将L描述为Head减去空列表,并且它并不关心递归的结果(deleteAll(Tail,_))。这就是为什么你得到未改变的第一个列表的结果。

考虑谓词应该描述的内容:两个列表列表之间的关系,其中第二个列表包含没有空格的第一个列表的子列表,除了最后一个子列表,没有改变:

:- set_prolog_flag(double_quotes, chars).

lists_withoutspace([X],[X]).                    % last list unaltered
lists_withoutspace([H1,H2|T1],[H1WoS|T2]) :-    % H1Wos:
   list_withoutspace(H1,H1WoS),                 % first sublist without spaces
   lists_withoutspace([H2|T1],T2).              % the same for the rests

对于list_withoutspace / 2,您可以使用te内置谓词char_type / 2来确定第一个list-element的类型:

list_withoutspace([],[]).          % empty list contains no space
list_withoutspace([X|T],L) :-      % X is not in the list
   char_type(X,space),             % if it is space
   list_withoutspace(T,L).         % relation must also hold for tail
list_withoutspace([X|T],[X|L]) :-  % X is in the list
   char_type(X,alpha),             % if it is a letter
   list_withoutspace(T,L).         % relation must also hold for tail

如果您想匹配多个字母,请相应更改alpha。如果查询此谓词,则会得到所需的结果:

   ?- lists_withoutspace([[q,' ',w,' ',e,' ',r,' ',t,' ',z],[a,' ',s,' ',d,' ',f,' ',g,' ',h],[y,' ',x,' ',c,' ',v,' ',b,' ',n]],L).
L = [[q,w,e,r,t,z],[a,s,d,f,g,h],[y,' ',x,' ',c,' ',v,' ',b,' ',n]] ? ;
no

或更紧凑:

   ?- lists_withoutspace(["q w e r t z","a s d f g h","y x c v b n"],L).
L = [[q,w,e,r,t,z],[a,s,d,f,g,h],[y,' ',x,' ',c,' ',v,' ',b,' ',n]] ? ;
no

答案 3 :(得分:0)

代码:

deleteAllSpaces_except_last([X],[X]):-!.                % without last Element

deleteAllSpaces_except_last([[]|Ys],[[]|Ys1]):-         % End of List inside List_of_lists
        deleteAllSpaces_except_last(Ys,Ys1).

deleteAllSpaces_except_last([[X|Xs]|Ys],Res):-          % if X=' ' then skip else add into New list inside list_of_lists
        (X=' ',Res=[Xs1|Ys1];Res=[[X|Xs1]|Ys1]),
        deleteAllSpaces_except_last([Xs|Ys],[Xs1|Ys1]).

测试:

| ?- deleteAllSpaces_except_last([[q,' ',w,' ',e,' ',r,' ',t,' ',z],[a,' ',s,' ',d,' ',f,' ',g,' ',h],[y,' ',x,' ',c,' ',v,' ',b,' ',n]],L).
L = [[q,w,e,r,t,z],[a,s,d,f,g,h],[y,' ',x,' ',c,' ',v,' ',b,' ',n]] ? ;
no

| ?- deleteAllSpaces_except_last([[q,' ',w,' ',e,' ',r,' ',t,' '],[],[y,' ',x,' ',c,' ',v,' ',b,' ',n]],L).
L = [[q,w,e,r,t],[],[y,' ',x,' ',c,' ',v,' ',b,' ',n]] ?