【问题标题】:Prolog replace every second item in listProlog替换列表中的每隔一个项目
【发布时间】:2021-09-16 23:08:23
【问题描述】:

我正在尝试学习 Prolog,但无法定义谓词:

在 Prolog 中定义一个谓词替换 (L1, X, L2),列表 L1 的每个第二个元素(从第二个元素开始)用元素 X 替换。

例子:

L1 = [a, b, c], X = 1, L2 = [a, 1, c]

L1 = [a, b, c, d], X = a, L2 = [a, a, c, a]

我试过这样:

replace( [], _, [] ) :- ! .
replace( [X|Xs], T, [Z1,Z2|Zs] ):-
  Z1 = X ,
  Z2 = T ,
  replace(Xs,T,Zs).

但它会将项目添加到第二个列表中,而不是替换它们。 提前感谢您的帮助。

【问题讨论】:

  • 您也必须从第一个列表中取出 2 个项目。第二项可以忽略(使用匿名变量_)。当L1 中的项目数为奇数时,您可能还需要添加另一个基本情况。
  • 您也可以在适当的地方使用相同的变量。因此,不要将Z1X 统一起来,只需在两个地方使用相同的变量XTZ2 也是如此。
  • 你可能会摆脱切割!,因为它在你的程序中不需要

标签: prolog


【解决方案1】:

您的问题是您一次从列表中拉出 1 个项目。要替换所有其他项目,您可以通过以下几种方式进行:

  • 一次取出 2 个物品

    尝试用这个替换偶数列表元素(其中列表中的第一个元素是项目编号 1。

    你有空列表的特殊情况:

    replace( [] , _ , [] ) .
    

    以及长度为 1 的列表的特例:

    replace( [X] , _ , [X] ) .
    

    然后是一般情况(长度 > 1 的列表):

    replace( [X,_|Xs] , R , [X,R|Ys] ) :- replace(Xs, R, Ys).
    

    综合起来,我们得到:

    replace( []       , _ , []       ) .
    replace( [X]      , _ , [X]      ) .
    replace( [X,_|Xs] , R , [X,R|Ys] ) :- replace(Xs, R, Ys).
    
  • 随时跟踪状态

    这并不难。它打开了可能性 使事情更普遍。为此,我们使用 helper 谓词。最终,它并没有太大的不同。

    首先,我们的replace/3 只是调用 辅助谓词,我们向其传递两个额外的状态位:

    • 当前索引值 (1),以及
    • 我们将用于确定哪些元素被替换的模数
    replace( Xs, R, Ys ) :- replace(Xs, R, 1, 2, Ys).
    

    这是谓词replace/5 的助手:

    replace( []     , _ , _ , _ , []     ) .
    replace( [X|Xs] , R , N , M , [Y|Ys] ) :-
      try_swap(X,R,N,M,Y),
      N1 is N+1,
      replace(Xs, R, N1, M, Ys ).
    
    try_swap( _ , R , N , M , R ) :- 0 is N mod M, !.
    try_swap( X , _ , _ , _ , X ) .
    

    把它们放在一起:

    replace( Xs, R, Ys ) :- replace(Xs, R, 1, 2, Ys).
    
    replace( []     , _ , _ , _ , []     ) .
    replace( [X|Xs] , R , N , M , [Y|Ys] ) :-
      try_swap(X,R,N,M,Y),
      N1 is N+1,
      replace(Xs, R, N1, M, Ys ).
    
    try_swap( _ , R , N , M , R ) :- 0 is N mod M, !.
    try_swap( X , _ , _ , _ , X ) .
    

【讨论】:

    【解决方案2】:

    你可以把它写成两个函数,依次递归调用自己。

    一个替换奇数位置的元素,另一个替换偶数位置的元素:

    replace_even([], _, [] ).
    replace_even([H|T], R, [H|O]) :-
        replace_odd(T, R, O).
    
    replace_odd([], _, []).
    replace_odd([_|T], R, [R|O]) :-
        replace_even(T, R, O).
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-08-02
      • 2022-07-18
      • 2016-03-28
      • 2019-12-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-10
      相关资源
      最近更新 更多