【问题标题】:Add to list if not already in list, change elements in list (PROLOG)如果尚未在列表中,则添加到列表中,更改列表中的元素(PROLOG)
【发布时间】:2014-04-19 02:05:55
【问题描述】:

我是 Prolog 的新手,我正在尝试编写一个函数来检查给定的键是否在列表中;如果是,它将增加列表中的值,否则将附加到列表的末尾。到目前为止,这是我的代码。

placeKey( Key, []       , List2 ) :- append(Key,[], List2).  %base case: append to empty list
placeKey( Key, [K|Rest] , List2 ) :-  %If front entry isnt the one we want then continue on the rest
  Key \= K ,
  put( Key ,Rest,List2).
placeKey(Key,[Key|Rest], List2):- %how to update item value?

但是,当项目不在给定列表中时,这只会返回一个列表,我什至不知道如何解决实际更改列表中项目的问题。任何帮助将不胜感激!

【问题讨论】:

    标签: list prolog append


    【解决方案1】:

    这样的?

    这使用Key/Count 形式的元组来表示每个列表项。

    add_or_increment( Dict , K , Updated ) :-     % to add or increment a tuple in a dictionary-like list
      nonvar(K) ,                                 % - the key must be bound.
      append( Prefix , [K/N|Suffix] , Dict ) ,    % - use the key to find the tuple in the list.
      ! ,                                         % - eliminate the choice point.
      M is N+1 ,                                  % - increment the count
      append( Prefix , [K/M|Suffix] , Updated )   % - construct the updated list
      .                                           % - Easy!
    add_or_increment( Dict , K , [K/1|Dict] ) :-  % otherwise, just prepend the key to the source list to create the updated list
      nonvar(K)                                   % - assuming, of course, that the key is bound.
      .                                           % - Even easier!
    

    【讨论】:

      【解决方案2】:

      有几种方法可以包含“键值”。一种是将键值对与连字符函子一起使用。我将steal大量借鉴 CapelliC 对基本问题的出色回答,并添加关键的制表逻辑:

      % Key not present, then it goes in with count 1
      place_key(Key, [], [Key-1]).
      
      % Key is at the head, then it's included in the new list with incremented count
      % and the rest of the list is unchanged
      place_key(Key, [Key-V|Rest], [Key-V1|Rest]) :-
          V1 is V+1.
      
      % Current head is not the key, so it's just copied over and the rest
      % of the list is processed
      place_key(Key, [K-V|Rest], [K-V|List2]) :-
          Key \= K,
          place_key(Key, Rest, List2).
      

      所以,例如:

      | ?- place_key(x, [], L).
      
      L = [x-1] ? ;
      
      no
      | ?- place_key(x, [x-2,y-3,z-1], L).
      
      L = [x-3,y-3,z-1] ? ;
      
      no
      | ?- place_key(w,[x-2,y-3,z-1], L).
      
      L = [x-2,y-3,z-1,w-1] ? ;
      
      no
      

      键值格式的一个很好的方面是 ISO Prolog 定义了一个谓词 keysort/2 来识别它。

      | ?- place_key(q,[x-2,y-3,z-1], L), keysort(L, LX).
      
      L = [x-2,y-3,z-1,q-1]
      LX = [q-1,x-2,y-3,z-1] ? ;  % List sorted by key
      
      no
      | ?-
      

      您也可以使用两个元素的子列表 ([Key,Value]) 来执行此操作,这可能是最初的意图,尽管尚不清楚。如果需要,上述逻辑很容易适应这种格式。 (在任何有K-V 模式的地方,都用[K,V] 替换它。)如果你对这样的列表进行列表排序,它仍然会按键排序:

      | ?- sort([[c,1],[x,4],[d,5],[a,6],[m,2]], L).
      
      L = [[a,6],[c,1],[d,5],[m,2],[x,4]]
      
      yes
      | ?-
      

      【讨论】:

        【解决方案3】:

        我会使用模式匹配而不是“命令”来解决任务:

        placeKey(Key, [], [Key]).
        placeKey(Key, [K|Rest], [K|List2]) :- Key \= K, placeKey(Key, Rest, List2).
        ...
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-02-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多