这可以非常类似于your other problem。这里有相关的想法。
由于您的结果有计数器,您将需要保留一个正在运行的重复元素列表。因此,考虑一个辅助谓词,其中包含当前正在运行的重复列表。这种“运行列表”通常在Prolog中使用,并被称为累加器。现在
split(L, C) :-
split(L, [], C). % Start repeat list accumulator at []
你需要考虑几个不同的情况:
split([], _, []). % This is an easy one!
这是说,如果我压缩空单,我得到一个空列表。
split([H], A, [[H|A]]). % This is an easy one!
这一个说,如果我收集一个元素的列表和我目前正在运行的重复列表A
,那么结果是[[H|A]]
。
split([H, H|T], A, TC) :-
...
这是我有一个正在运行的重复列表,A
的情况下,元素仍然重复。结果将是一个列表TC
,但我不知道它看起来像什么,因为我们仍处于重复周期,它将需要通过递归确定。这个谓词应该是什么样子?在本节中将需要递归调用split1
将有一个新的累加器列表。它是什么样子的?。
split([H1, H2|T], A, [[H1|A]|TC]) :-
dif(H1, H2),
...
这是我有一个正在运行的重复列表,A
,并在H1
重复停止的情况。由于当前周期的重复与H1
结束,我们知道结果看起来像[[H1|A]|TC]
因为重复周期与H1
完成,整个重复列表H1
与尾部A
(这只是预先考虑到H1
A
,和他们都相同的元素)。我们还没有通过递归来确定列表TC
的其余部分。这个谓词实现应该是什么样的?
还有其他方法可以完成上述逻辑(例如,使用->
和;
结构等),但这样做会使它变得简单。
尝试将这些看作是规则,其中谓词子句的头部是断言,如果子句的以下元素为真,断言将为真。并递归思考。
作为一种事后,这可以无需单独的蓄电池使用结果进行累加器完成:
split([], []).
split([H], [[H]]).
split([H1,H2|T], [[H1]|R]) :-
dif(H1, H2),
split(...). % left as an exercise
split([H,H|T], [[H|TH]|R]) :-
split(...). % left as an exercise
什么,当你试图评估你的断言会发生什么?你期望会发生什么?你是否试图追踪你的程序以查看它出错的地方(如果有的话)? –
你对'[a,a,a,b,b,a,b,a,a]'有何期望? – repeat
[[a,a,a],[b,b],[a],[b],[a,a]] –