Prolog 如何在不剪切的情况下从列表中删除第一个匹配元素
我试图在不使用回溯的情况下从列表中删除第一个匹配项,基本上是元素的第一次出现,然后停止回溯,不再提供更多的解决方案 我有一个非常有效的方法:Prolog 如何在不剪切的情况下从列表中删除第一个匹配元素,prolog,Prolog,我试图在不使用回溯的情况下从列表中删除第一个匹配项,基本上是元素的第一次出现,然后停止回溯,不再提供更多的解决方案 我有一个非常有效的方法: % delete an item from a list, only one, no back tracking, using cut delete_one( X, [X|Tail], Tail ) :- !. delete_one( X, [Y|Tail], [Y|Tail1] ) :- delete_one(X,Tail,Tail1). 这很有效。我
% delete an item from a list, only one, no back tracking, using cut
delete_one( X, [X|Tail], Tail ) :- !.
delete_one( X, [Y|Tail], [Y|Tail1] ) :- delete_one(X,Tail,Tail1).
这很有效。我的问题是在不使用cut的情况下实现相同的目标,而是使用not
谓词。这就是我尝试过的:
% the same as above without using cut
delete_one_no_cut(X,[X|Tail],Tail).
delete_one_no_cut(X,[Y|Tail],[Y,Tail1]) :-
not(X==Y),
delete_one_no_cut(X,Tail,Tail1).
它不起作用。你能帮我吗?操作顺序。大多数递归问题有1或2个终止特殊情况和一个一般递归情况。您有两种特殊情况:
x_list_list2(X,[X|T],T).
x_list_list2(X,[H|T],[H|New]):-
dif(X,H),
x_list_list2(X,T,New).
- 一旦你找到一个空列表,你就完成了
- 一旦你在列表的最前面找到一个匹配的词,你就完成了
- 列表的标题与提供的值不匹配
delete_first( _ , [] , [] ) .
delete_first( X , [H|T] , [H|T1] ) :- X \= H , delete_first(X, T, T1 ) .
delete_first( X , [X|T] , T ) .
操作顺序。大多数递归问题有1或2个终止特殊情况和一个一般递归情况。您有两种特殊情况:
- 一旦你找到一个空列表,你就完成了
- 一旦你在列表的最前面找到一个匹配的词,你就完成了
- 列表的标题与提供的值不匹配
delete_first( _ , [] , [] ) .
delete_first( X , [H|T] , [H|T1] ) :- X \= H , delete_first(X, T, T1 ) .
delete_first( X , [X|T] , T ) .
注意第二类的第三个参数中的
,
。它应该是[Y | Tail1]
。另外,不要使用not/1
而使用\+/1
或直接使用X\=Y
(或dif/2
)注意第二类第三个参数中的,
。它应该是[Y | Tail1]
。另外,与使用not/1
相反,使用\+/1
或直接使用X\=Y
(或dif/2
)为什么要在我的版本上使用此版本?我的版本考虑了空列表。如果源列表为空或未找到匹配项,则您的操作将失败。此外,您的解决方案使用的是dif/2
,这不是标准的ISO prolog。请求使用的是not
/1,而A\=B
在语义上与not(A=B)
相同,而dif/2
则不是。好吧,我认为如果找不到,失败是有意义的,您的delete_first(X,[1,2],Y),X=2失败。
这可能是一个问题,取决于使用情况<代码>非/1和\=
实现有一个缺口,我想。为什么你要使用这个版本而不是我的版本?我的版本考虑到了空列表。如果源列表为空或未找到匹配项,则您的操作将失败。此外,您的解决方案使用的是dif/2
,这不是标准的ISO prolog。请求使用的是not
/1,而A\=B
在语义上与not(A=B)
相同,而dif/2
则不是。好吧,我认为如果找不到,失败是有意义的,您的delete_first(X,[1,2],Y),X=2失败。
这可能是一个问题,取决于使用情况<代码>非/1和\=
我认为实现有一个缺口。