[[A,B,2000],[C,D,2008],[F,G,2004]]
如上例所示,如何对基于每个列表中的最后一个元素组成的列表列表进行排序,并返回前两个元素。那是[[A,B],[F,G],[C,D]]
。
请注意,以大写字母开头的单词是变量,而不是原子。从问题陈述中尚不清楚,是否打算将列表元素用作变量。我假设它们是变量,因为它不会影响建议的解决方案。
可能有很多方法可以做到这一点,但是我不认为这是一种最佳方法:
1)用于setof
以不同的顺序收集排序的值。也就是说,将您的列表收集为一个新列表,如下所示:[[2000,A,B],[2004,F,G],[2008,C,D]]
。假设每个列表项都是唯一的(没有所需的重复项)。
2)编写一个简单的谓词,遍历新列表并剥离每个子列表的第一个元素。
最终的解决方案如下所示:
process( L, Result ) :-
setof([Z,X,Y], member([X,Y,Z], L), SortL), % gives list like shown above
stripyear(SortL, Result).
stripyear
是将遍历每个列表项并去除年份(每个子列表的第一个元素)的谓词。它非常简单,并遵循基本的Prolog列表处理原则:
stripyear([[_,B,C]|T1], [[B,C]|T2]) :-...
这里main子句的开头说,如果我的输入是一个看起来像的列表[[_,B,C]|T1]
,那么输出就是一个看起来像的列表[[B,C]|T2]
。也就是说,第二个列表的头部是第一个列表的头部,其中第一个元素已删除。我们不在乎该元素的值是什么,因此我们_
用来显示它。但是然后我们需要处理T1
和T2
。它们有什么关系?我已经照顾好了头。尾部以相同的方式递归相关:第二个列表的尾部是除去年份(第一个子列表元素)的第一个列表的尾部:stripyear(T1, T2)
。因此,完整的主要子句如下所示:
stripyear([[_,B,C]|T1], [[B,C]|T2]) :- stripyear(T1, T2).
很好,但是如何停止呢?如果我有一个空列表(striplist([], ?)
),该怎么办?该列表[]
不匹配,[[_,B,C]|T1]
因为它没有头或尾。它是空的。而且如果没有条款来处理它,striplist([], Result)
将会失败。因此,我需要一个子句单独处理它,这也得出了递归的结论:
stripyear([], []).
这表示,如果我从空列表中删除年份,则会得到一个空列表。很合逻辑。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句