【问题标题】:I'm trying to remove a single occurrence of an element in a list我正在尝试删除列表中单个元素的出现
【发布时间】:2021-10-19 12:11:15
【问题描述】:

我正在使用 prolog,我正在尝试从列表中删除 1 个元素。如果我要查找的元素是列表中的第一个元素,我的附加代码可以正常工作,但如果它是列表中的第二个元素,它只会显示 false。我哪里错了

deleteFirst([A|X],B,Y,R):-
    A\=B,
    appendL(Y,A,[],Y1),
    deleteFirst(X,B,Y1,R).

deleteFirst([A|X],A,Y,R):-
    appendL(Y,X,[],R).

【问题讨论】:

  • 见:convlist/3
  • 在 SWI-Prolog 中,您可以简单地这样做:?- select(c, [a,b,c,d,e], Rest). Rest = [a, b, d, e].

标签: prolog


【解决方案1】:

试试这样的:

% ---------------------------------------------
% remove the first X from List, yielding Result
% ---------------------------------------------
delete_first( X , List , Result ) :-
  append( Prefix, [X|Suffix], List ) ,
  ! ,
  append( Prefix, Suffix, Result ) .

需要切割来消除选择点:否则,在回溯时,它会将删除的项目放回原处并尝试找到另一个匹配的X。

如果您要自己滚动(我想这就是您的讲师想要的),像这样,只需遍历列表即可:

delete_first( _ , []     , []     ) .  % Remove this to fail if no matching X is found
delete_first( X , [X|Rs] ,    Rs  ) :- % Once we find an X, we're done.
  !.                                   % - and eliminate the choice point
delete_first( X , [Y|Ys] , [Y|Rs] ) :- % Otherwise, put Y on the result list and recurse down
  delete_first( X , Ys, Rs ) .

【讨论】:

  • 这样的谓词不加删减会好很多。用户可能希望它列举替代解决方案,而 cut 阻止了这种情况。另一方面,如果用户不想要替代解决方案,他们可以轻松地自己进行切割。或者您可以提供一个纯版本和一个带有剪切的delete_first_det 包装器。
  • @IsabelleNewbie — 您可能已经注意到 O.P. 的问题是关于从列表中删除 first 匹配 X。因此,由于从列表中删除其他替代匹配 Xs ,因此剪切不是问题陈述的一部分。因此,关于为什么削减到位的评论。
  • 我们中的一个人误读了这个问题,我认为不是我。 OP 说他们的定义适用于删除 列表的第一个元素。我没有看到他们在任何地方谈论第一个 matching 元素。即便如此,我的第二点仍然是:通用解决方案 + 切割包装优于埋在内部某处的切割。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-05-12
  • 1970-01-01
  • 2020-08-08
  • 1970-01-01
  • 2021-08-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多