Prolog:如何从列表中删除子列表? (后续问题) [英] Prolog: How do I delete a sublist from a list? (Follow-up Question)

查看:141
本文介绍了Prolog:如何从列表中删除子列表? (后续问题)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Prolog的新手,并且对Prolog中的递归不太了解,因此我不确定如何从已经考虑的列表中删除元素.

New to Prolog and don't understand recursion in Prolog very well so I am not sure how to take out an element in a list that has already been considered.

这是我之前的问题的后续问题: Prolog:如何在两个列表之间进行迭代(嵌套循环)?

This is a follow-up question to my previous question: Prolog: How do you iterate between two lists (nest for-loop)?

我有两个列表:

stringList([hello, hi], [bye,later], X).

函数stringList如下所示:

where the function stringList looks like:

stringList(As, Bs, [A,B]) :-
  member(A, As),
  member(B, Bs).

这将产生输出:

X = [hi, bye] ;
X = [hi, later] ;
X = [hello, bye] ;
X = [hello, later].

现在我要从两个列表中删除子列表.例如,如果X = [ later],我想拿出hi,然后再取出,所以我的下一个X = [hello, bye].当我的清单很大时,这一点变得尤为重要.

Now I want delete the sublist from the two lists. For example if X = [ later], I want to take out hi and later so my next X = [hello, bye]. This becomes more important when my list is big.

我知道我需要递归,所以我创建了基本案例:

I know I need to recurse so I created the base case:

stringList([],[],[]).

推荐答案

一种方法是使用findall/3delete/3谓词.当前,您的stringList/3一次生成一个解决方案,因此您需要使用findall/3将所有这些解决方案收集到一个列表中,然后删除所需的任何内容:

One way would be to use findall/3 and delete/3 predicates. Currently your stringList/3 generates solutions one at a time, so you need to gather all this solutions in one list using findall/3 and then delete whatever you want:

deleteSublist(As, Bs, Elem, L):- 
       findall([X,Y], stringList(As, Bs, [X,Y]), L1),
       delete(L1, Elem, L).

示例:

?- deleteSublist([hello, hi], [bye,later], [hi,_], L).
L = [[hello, bye], [hello, later]].

在上面的示例中,要删除的元素可能只是[bye],但是我们使用[_]删除所有出现的hi.

In the above example the element you want to delete could be just [bye] but we use [_] to delete all occurrences of hi.

现在要回答您的问题,可以使用递归轻松完成,但是要使用递归,您需要将所有解决方案都放在一个列表中,以便稍后您可以从该列表中递归提取元素.上述解决方案中的递归部分隐藏在delete/3内置的内部.因此,如果您想使用自己的递归解决方案,只需编写自己的delete/3递归定义(我认为必须在堆栈溢出中询问此定义,以便您可以搜索或搜索它...)

Now to answer your question this could be easily done with recursion but in order to use recursion you need all the solution in one list so that later you can recursively extract elements from that list. The part of recursion in the above solution is hidden inside built in delete/3. So if you want to use your own recursive solution just write your own recursive definition of delete/3 (I think this must be already asked in stack overflow so you might search it or google it...)

另一件事,如果您希望您的解决方案像stringList/3谓词中那样一次生成一个解决方案,那么您也可以在下面使用这种简单方法:

Another thing, if you want your solution to generates one solution at a time like in stringList/3 predicate you could also use this simple way below:

?- stringList([hello, hi], [bye,later], X),(X \= [hi,_]).
X = [hello, bye] ;
X = [hello, later] ;
false.

在上文中,我们利用了以下优势:例如,比较[bye] \= [_]\=会失败,而如果您使用纯dif/2会成功:

In the above we take the advantage that \= fails when e.g comparing [bye] \= [_] while if you used the pure dif/2 this would succeed:

?- stringList([hello, hi], [bye,later], X),dif(X,[hi,_]).
X = [hello, bye] ;
X = [hello, later] ;
X = [hi, bye] ;
X = [hi, later].

因此,使用dif/2时,您将需要更详细的限制:

So using dif/2 you would need more detailed restriction:

?- stringList([hello, hi], [bye,later], X),dif(X,[hi,bye]), dif(X,[hi,later]).
X = [hello, bye] ;
X = [hello, later] ;
false.

这篇关于Prolog:如何从列表中删除子列表? (后续问题)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆