sublist(L1,L2,I,J)
我有一个列表,L1
被传入,还有2个索引I
和J
,我希望L2
成为包含两个元素之间元素的包含子列表I
和J
。
如果J
超出范围,我希望它从I
转到列表的末尾。同样,如果I
小于0,我想让它从列表的开头到J
。
I
> J
返回空列表。
到目前为止我所拥有的:
sublist(_,[],I,J):-
I > J.
sublist(Xs,Ys,I,Length):-
length(Xs,Length),
N > L,
sublist(Xs,Ys,I,J).
sublist([X|_],[X],1,1).
sublist([X|Xs],[X|Ys],1,J):-
J > 1,
J1 is J - 1,
sublist(Xs,Ys,1,J1).
sublist([_|Xs],Ys,I,J):-
I > 1,
I1 is I - 1,
J1 is J - 1,
sublist(Xs,Ys,I1,J1).
答案 0 :(得分:4)
您可以通过重新思考策略来解决这个问题。
首先,您的基本情况是什么?
I > J
在这两种情况下,您都会将空列表附加到目前为止的任何内容,并将其称为好。
接下来,你关心的边缘情况是什么?
J
超出了列表的末尾I
位于列表的开头在第一种情况下,您只需遍历输入列表的末尾。在第二步中,您从输入列表的开头开始。
好的,让我们尝试实现它,我将使用累加器并围绕它进行调用。
sublist(L1, L2, I, J):-
sublist(L1, Temp, I, J, []),
!,
reverse(Temp, L2).
我们将输入列表L1
,一个变量统一为输出列表L2
,以及索引I
和J
。我正在使用cut
,因此我不必担心其他解决方案的回溯,并反转它,因为累积列表是反向构建的。
让我们研究基本案例。
清空列表作为输入,只需将累加器与输出列表统一起来。我们现在不关心指数。事实证明,这也满足了J
超出列表末尾的边缘情况。从那时起,我们将所有输入列表累积到累加器中,并且仍然有剩余的J值。
sublist([], L2, _I, _J, L2).
我> J再次将累加器与输出列表统一起来。我们不再关心输入列表了。
sublist(_L1, L2, I, J, L2):-
I > J.
现在是边缘案例。
列表末尾之外的 J
已在上面解决。
I
位于列表的开头之前,只需将该索引设置为0,然后继续。
sublist(L1, L2, I, J, L2):-
I < 0,
sublist(L1, L2, 0, J, L2).
现在我们只需要实现实际的逻辑。我们只想从正确的I
开始积累。所以让我们递减I
并丢弃输入列表的部分,直到我们到达我们想要的位置。为了使索引的结尾匹配,我们还需要递减J
。这样我们在指数之间保持相同的距离。
sublist([_L|Ls], L2, I, J, Acc):-
I > 0,
sublist(Ls, L2, I-1, J-1, Acc).
我们终于想到了。所以,让我们开始使用输入列表中的片段构建列表。这一直持续到我们遇到一个基本情况为止。之后,累加器将返回到原始sublist
子句。
sublist([L|Ls], L2, I, J, Acc):-
sublist(Ls, L2, I, J-1, [L|Acc]).
总而言之,我们最终得到:
sublist(L1, L2, I, J):-
sublist(L1, Temp, I, J, []),
!,
reverse(Temp, L2).
sublist([], L2, _I, _J, L2).
sublist(_L1, L2, I, J, L2):-
I > J.
sublist(L1, L2, I, J, L2):-
I < 0,
sublist(L1, L2, 0, J, L2).
sublist([_L|Ls], L2, I, J, Acc):-
I > 0,
sublist(Ls, L2, I-1, J-1, Acc).
sublist([L|Ls], L2, I, J, Acc):-
sublist(Ls, L2, I, J-1, [L|Acc]).
我们可以这样测试它:
?- sublist([1,2,3,4,5], S, 0,3).
S = [1, 2, 3, 4].
?- sublist([1,2,3,4,5], S, -1,30).
S = [1, 2, 3, 4, 5].
?- sublist([1,2,3,4,5], S, 3,1).
S = [].
?- sublist([1,2,3,4,5], S, 3,3).
S = [4].
?- sublist([1,2,3,4,5], S, 3,4).
S = [4, 5].
答案 1 :(得分:0)
我认为你在第二个条款中只有一些错字。尝试这种(未经测试的)校正,以满足您的要求
如果J超出界限,我希望它从我到列表的末尾。
sublist(Xs,Ys,I,J):-
length(Xs,Length),
J > Length,
sublist(Xs,Ys,I,Length).