【问题标题】:Prolog. I can't mix two lists序言。我不能混合两个列表
【发布时间】:2021-07-13 03:05:21
【问题描述】:

我想将两个列表合二为一。例如,[1,3,5][2,3,9] 将产生 [1,2,3,5,9]

我试过了:

mezclar( L1, L2, L3 ):-
  L1 = [Cab|Cola] ,
  L3 = [Cab,Cola2] ,
  mezclar(L2,Cola,Cola2) .
mezclar( L1, L2, L3 ):-
  L1=[] ,
  L3=L2 .

但我有两个问题。

  • 第一个问题是重复数字
  • 第二个是我正在将列表放入列表中,我不想这样做。

如果我执行

mezclar( [1,3,5], [2,5,9], X ).

我明白了

X = [1, [2, [3, [5, [5|...]]]]]

【问题讨论】:

  • mezclar(L1,L2,L3):-L1=[],L3=L2。梅斯克拉(L1,L2,L3):-L1=[Cab|Cola],梅斯克拉(L2,可乐,Cola1),L3=[Cab|Cola1]。现在我得到了排序的列表,但我遇到了与重复数字相同的问题
  • 在将每个元素添加到新列表之前,检查它是否已经存在。您可以使用 append/3 插入元素,并使用 member/2 检查它们是否已经在列表中
  • 如果您使用的是 SWI-Prolog,请参阅 ord_union/2 or ord_union/3

标签: list prolog


【解决方案1】:

要将两个列表合二为一,结果列表是有序且没有重复的,请尝试:

mezclar(L1,L2,L3) :- append(L1,L2,L4), sort(L4,L3).

查询:

mezclar([1,3,5], [2,5,9], X).

会产生结果:

X = [1, 2, 3, 5, 9]

此示例使用sort/2。这是sort/2 的 SWI 文档的链接:

http://eu.swi-prolog.org/pldoc/man?predicate=sort/2

【讨论】:

    【解决方案2】:

    输入列表是否排序?如果是这样,您可以很快将它们合并。

    merge([], Xs, Xs).
    merge([X|Xs], [], [X|Xs]).
    merge([X|Xs], [Y|Ys], [X|Zs]) :- X < Y, merge(Xs, [Y|Ys], Zs).
    merge([X|Xs], [Y|Ys], [Y|Zs]) :- X > Y, merge([X|Xs], Ys, Zs).
    merge([X|Xs], [X|Ys], [X|Zs]) :- merge(Xs, Ys, Zs).
    

    【讨论】:

      【解决方案3】:

      假设您的列表是有序的,那么您似乎正在查看直接合并。这很简单:

      merge( []     , []     , []       ) .  % merging two empty lists yields the empty list itself
      merge( []     , [Y|Ys] , [Y|Ys]   ) .  % merging the empty list with a non-empty list yields the non-empty list 
      merge( [X|Xs] , []     , [X|Xs]   ) .  % merging a non-empty list with the empty list yields the non-empty list
      merge( [X|Xs] , [Y|Ys] , [X,Y|Zs] ) :- % otherwise, when both lists are non-empty...
        X @= Y ,                             % - if X and Y compare as equal (in the standard order of terms)
        merge( Xs, Ys, Zs ) .                % - Take both X and Y and recurse down on the tail(s).
      merge( [X|Xs] , [Y|Ys] , [X|Zs] ) :-   % otherwise, when both lists are non-empty...
        X @< Y ,                             % - if X compares low to Y (in the standard order of terms)
        merge( Xs, [Y|Ys], Zs ) .            % - Take X and recurse down on the tail(s).
      merge( [X|Xs] , [Y|Ys] , [X|Zs] ) :-   % otherwise, when both lists are non-empty...
        X @> Y ,                             % - if X compares hight to Y (in the standard order of terms)
        merge( [X|Xs], Ys, Zs ) .            % - Take Y and recurse down on the tail(s).
      

      以上不会消除集合中的重复,也不会统一任何未绑定的变量。如您所料,将[1,3,5][1,3,5] 合并产生[1,1,3,3,5,5]。如果您想要类似集合的语义,则需要修改最后 3 个子句以使用不同的比较/统一运算符。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-06-27
        • 2019-04-27
        • 1970-01-01
        • 2019-04-24
        • 2019-11-22
        • 1970-01-01
        • 2021-07-05
        相关资源
        最近更新 更多