【问题标题】:Prolog: delete all spaces in listProlog:删除列表中的所有空格
【发布时间】:2016-04-24 14:15:27
【问题描述】:

我有这样的列表:

[[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]

所以似乎连 subtract 都不匹配 [ ] 作为空格。 我怎样才能做到这一点?

【问题讨论】:

  • 你如何表示空间?你需要写' '

标签: recursion prolog


【解决方案1】:
:- 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(差异(''),Cs,Ds)。

使用if_/3tfilter/3

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

【讨论】:

    【解决方案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_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
    

    【讨论】:

    • s(X)。额外问题:如何自动找出/测试(无需阅读所有文档)哪些内置/库谓词对我的口味足够纯?
    • @repeat:我可能会尝试logical-purity 的标签信息中的两个特征。在这种情况下,如果实例化一个参数,则 char_type/2 (我假设这是您所指的内置函数)成功,但泛化,最一般的查询,会导致实例化错误。但是,我使用第二个参数的方式始终是 space 并且以这种方式使用它不会破坏连接的交换性,例如?- X=' ', char_type(X,space).?- char_type(X,space), X=' '. 产生相同的结果。在这种情况下,这对我来说已经足够了。
    • 谢谢 4 你的回复!对我来说听起来不错...只是想知道如何自动检查它,以帮助程序员/编码器/用户/我自己看到纯和不纯之间的界限。
    • 现在是实现predicate_algebraicproperties/2 的最佳时机;) 或许需要一些帮助,例如“我保证memberd/2 是纯正的”...您对此有何看法?
    • 如果它不存在,我们应该制作它。严重地!我的看法:(1)纯代码和非纯代码都可以获利,(2)它可以很好地与元谓词(例如,maplist/3 是纯的,如果它的第一个参数是纯的),(3)我们只能获胜,因为“降低预期”,(4) 它消耗了大量的处理器周期,并希望指出一些见解。
    【解决方案3】:

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

    基于tfilter/3dif/3 定义 spaces_gone/2 像这样:

    :- use_module(library(lists), [same_length/2, reverse/2, maplist/3])。 空格([],[])。 space_gone([A|As], [D|Ds]) :- 相同长度(As,Ds), 反向([A|As],[Last|Bs]), maplist(tfilter(dif('')), Bs, Cs), 反向([最后|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
    

    【讨论】:

      【解决方案4】:

      代码:

      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]] ? 
      

      【讨论】:

      • deleteAllSpaces_except_last([[C],[]], Xs). 应该给出两个答案
      • @false 我加了deleteAllSpaces_except_last([[]],[]). ?
      • X = a, deleteAllSpaces_except_last([[X],[]],[[X],[]]). 正确成功,但同样没有X = a 失败。
      • @false 我该如何解决?
      • X = ' ' -> ... 提交过早。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-09-23
      • 1970-01-01
      • 2020-07-05
      • 1970-01-01
      相关资源
      最近更新 更多