查找列表的连续子列表

时间:2019-09-28 19:37:25

标签: prolog

我想写一个谓词split/2来生成在另一个列表中找到的所有连续列表。


示例split([1,2,3,4],X)应该返回 X = [4]X = [2,3]X = [1,2]X = [1,2,3]等。

到目前为止,我只有一个谓词,它返回列表的所有可能的子列表:

sublist([],[]).
sublist([H|T], [H|R]) :-
    sublist(T,R).
sublist([_|T], R) :-
    sublist(T,R).

但是,对于示例中的查询,该谓词包括在[1,2,3,4]中找不到的不需要的答案,例如X = [2,4]X = [1,3]

1 个答案:

答案 0 :(得分:0)

通常,将问题分解为多个子问题会更容易。我们首先可以构造一个谓词,该谓词将构造给定列表的所有后缀

我们可以这样构造谓词:

suffix(_, []).
suffix([H|T], [H|T2]) :-
    suffix(T, T2).

因此,对于列表中的每个点,我们可以决定停止(列表为空)或发出下一个项目。对于给定的样本列表,我们得到:

?- suffix([1,2,3,4],X).
X = [] ;
X = [1] ;
X = [1, 2] ;
X = [1, 2, 3] ;
X = [1, 2, 3, 4].

现在,我们只需要决定何时开始后缀。对于列表中的每个项目,我们可以决定从这一点开始,并枚举我们随后附加到该项目的所有后缀:

split([H|T], [H|S]) :-
    suffix(T, S).
split([_|T], S) :-
    split(T, S).

例如:

?- split([1,2,3,4],X).
X = [1] ;
X = [1, 2] ;
X = [1, 2, 3] ;
X = [1, 2, 3, 4] ;
X = [2] ;
X = [2, 3] ;
X = [2, 3, 4] ;
X = [3] ;
X = [3, 4] ;
X = [4] ;
false.

令人高兴的是,我们获得了第二个谓词“免费”:我们还可以获得列表的所有后缀。

我们可能还希望包括空列表。我将其保留为练习。