使用Prolog在列表中查找重复的子列表

时间:2013-06-29 10:30:43

标签: prolog

我想用以下输出编写一个prolog谓词:

?- all_match([1,2,3,2,3,1,2],L).
L = [[], [1], [1, 2], [2], [2, 3], [3]].

?- all_match([1,1,1,2],L).
L = [[], [1], [1, 1]].

目的是找到不止一次重复的子列表。 到目前为止,我找到了在列表中查找所有子列表的解决方案 -

subSet(_, []).
subSet(L, [S|T]) :- append(_, L2,L), append([S|T], _, L2).

但我无法弄清楚如何重复搜索每个元素。

提前致谢。

2 个答案:

答案 0 :(得分:2)

此代码与您的要求略有不同,因为all_match / 2将省略空序列,如果输入中没有重复的子序列,则会失败。

repeated(List, Sublist) :-
        % For all prefixes, suffixes:
        append(Sublist, Tail, List), Sublist \= [],
        % For all suffixes of the former suffixes:
        append(_, TailTail, Tail),
        % Is the head of the latter suffix equal to the head of the input?
        append(Sublist, _, TailTail).
repeated([_|List], Sublist) :-
        % Strip leading character and continue
        repeated(List, Sublist).

all_match(List, Lists) :-
        % Aggregate all repeated sequences or fail if there weren't any.
        setof(L, repeated(List, L), Lists).

重复/ 2的第一个条款概念的草图:

|----------------List------------------|  repeated(List, Sublist)
|--Sublist--|------------Tail----------|  append(Sublist, Tail, List)
|--Sublist--|       |-----TailTail-----|  append(_, TailTail, Tail)
|--Sublist--|       |--Sublist--|      |  append(Sublist, _, TailTail)

结果:

?- all_match([1,2,3,2,3,1,2],L).
L = [[1], [1, 2], [2], [2, 3], [3]].

更新以允许重叠序列:

repeated([H|List], Sublist) :-
        append(Sublist, _, [H|List]), Sublist \= [],
        append(_, Tail, List),
        append(Sublist, _, Tail).
repeated([_|List], Sublist) :-
        repeated(List, Sublist).

答案 1 :(得分:2)

我喜欢Kay的回答(+1)。这里是thema的变种

all_match(L, M) :-
    take(L, M, R),
    take(R, M, _).

take(L, [A|B], R) :-  % use [A|B] to remove empties
    append(_, T, L),
    append([A|B], R, T).

产量

?- setof(L,all_match([1,2,3,2,3,1,2],L),R).
R = [[1], [1, 2], [2], [2, 3], [3]].