List 删除给定数字N的列表中的子列表,该数字表示PROLOG中的连续元素

List 删除给定数字N的列表中的子列表,该数字表示PROLOG中的连续元素,list,prolog,sublist,List,Prolog,Sublist,我正在尝试解决一个序言练习。它说,如果F是从I中移除元素数量的结果,如N所说,从位置P开始,它就起作用。 我还有一些基本情况需要解决: 如果起始位置(P)大于初始列表(I)长度,则得到I 如果要删除的元素数量(N)大于列表中的元素数量 从给定位置(P)开始,它将删除所有元素,直到结束,作为一个 结果是一个空列表 如果要移除的元素数量(N)为零,则结果为I 这里有一些例子: ?- remove_at([],7,3,F).% working F = [] ?- remove_at([k1,k2]

我正在尝试解决一个序言练习。它说,如果F是从I中移除元素数量的结果,如N所说,从位置P开始,它就起作用。 我还有一些基本情况需要解决:

  • 如果起始位置(P)大于初始列表(I)长度,则得到I
  • 如果要删除的元素数量(N)大于列表中的元素数量 从给定位置(P)开始,它将删除所有元素,直到结束,作为一个
    结果是一个空列表
  • 如果要移除的元素数量(N)为零,则结果为I
这里有一些例子:

?- remove_at([],7,3,F).% working
F = []
?- remove_at([k1,k2], 5, 3,F).%working
F=[k1,k2]
?- remove_at([k1,k2], 2, 5,F).%need help
F=[k1]
?- remove_at([k1,k2,k3,k4,k5], 1, 2,F).%need help
F=[k3,k4,k5]
我所拥有的代码根本不起作用,只是在我指出的两个案例中需要帮助:

remove_at([],_,N,[]):-!.                  % for the base case
remove_at( Xs , _ , 0 , Xs ).             % both counts are done to zero: we're done.
remove_at( [X|Xs] , P , N , [X|Ys] ) :-   % otherwise...
P > 0 ,                                   % - when P > 0
P1 is P-1 ,                               % - decrement P
remove_at(Xs,P1,N,Ys).                    % - recurse down , adding the head of the     source list to the result list                                     
remove_at( [X|Xs] , 0 , N , Ys ) :-       % otherwise...
N > 0 ,                                   % - when N is > 0
N1 is N-1 ,                               % - decrement N
remove_at( Xs , 0 , N1 , Ys ).            % recurse down, discarding the head of the source list.

我不确定这是否涵盖了所有基本情况,但您可以这样处理:

remove_at( Xs , 0 , 0 , Xs ) .            % both counts are done to zero: we're done.
remove_at( [X|Xs] , P , N , [X|Ys] ) :-   % otherwise...
  P > 0 ,                                 % - when P > 0
  P1 is P-1 ,                             % - decrement P
  remove_at(Xs,P1,N,Ys)                   % - recurse down , adding the head of the source list to the result list
  .                                       %
remove_at( [X|Xs] , 0 , N , Ys ) :-       % otherwise...
  N > 0 ,                                 % - when N is > 0
  N1 is N-1 ,                             % - decrement N
  remove_at( Xs , 0 , N1 , Ys )           % recurse down, discarding the head of the source list.
  .
或者你可以把它分解成更小的问题,列出下面的问题。我们创建一个helper谓词(
partition/4
),该谓词将列表拆分为最多指定长度的前缀和后缀,由剩余部分组成

剩下的很简单:我们调用
partition/4
prefix来获得我们想要保留的前缀和它的余数,然后我们将余数划分为它的前缀,我们想要丢弃的元素和它的后缀,我们想要保留的尾部元素,然后用我们想要保留的后缀附加我们想要保留的前缀,生成结果列表

remove_at( Xs , P , N , Ys ) :-
  partition(Xs,P,Pfx,Ts) ,       % split the source list into a prefix (Pfx) of [at most] length P and a suffix (Ts), consisting of the remainder.
  partition(Ts,N,_,Sfx) ,        % partition that suffix into a prefix (_) of [at most] length N (the elements to discard) and a suffix (Sfx) consisting of the remainder.
  append( Pfx, Sfx , Ys )        % append Pfx and Sfx to create the result list (Ys).
  .                              % Easy!

partition( Xs , 0 , [] , Xs ) .         % success if the count is down to zero: finalize the prefix.
partition( [X|Xs] , N , [X|T] , R ) :-  % otherwise...
  N > 0 ,                               % - when N > 0
  N1 is N-1 ,                           % - decrement N
  partition( Xs , N1 , T , R )         % - recurse down, prepending the head of the source list to the prefix.
  .

正如他们所说,有不止一种方法可以做到这一点。

尼古拉斯的想法是正确的。下面是一个更正的版本:

% Removing items from empty list is empty list
remove_at([], _, _, []).

% Remove 0 items gives the same list back
remove_at(L, _, 0, L).

% To remove items starting at location P, allow the head of the input
% to be in the output, and remove items starting at location P-1 in the tail.
remove_at([X|T], P, N, [X|R]) :-
    P > 1,
    P1 is P-1,
    remove_at(T, P1, N, R).

% Primary case: remove items starting at current position 1
% Remove the head, then remove N-1 items from the tail.
remove_at([_|T], 1, N, R) :-
    N > 0,
    N1 is N-1,
    remove_at(T, 1, N1, R).

示例代码中参数的定义与问题语句完全不一致。您的问题陈述说,第二个和第三个参数应该分别是起始索引和计数。但是您的示例有一个列表元素作为第二个参数,而不是开始索引。我认为你需要在一个起点上再尝试一次。逻辑地考虑一下:您需要一个对空列表进行操作的
remove_at
的基本情况,或者处理第三个参数=<0,或者类似的情况。不过,您现在拥有的与问题无关。旁注:谓词名称和插入参数之间不允许有空格。因此,我相应地编辑了您的帖子。您最新版本的
remove_at
只接受3个参数,但您的示例都需要4个参数。在第一个解决方案中(我没有尝试第二个)
remove_at([],7,3,F)。
返回“false”。他的要求是它返回
F=[]
<代码>在([k1,k2],5,3,F)处删除。也返回false,但预期结果是
[k1,k2]
。空列表需要一个额外的基本情况,现有基本情况的第二个参数应该是
。第一个解决方案中的结果为false…第四个解决方案中的结果是[k1,k4,k5],而不是[k3,k4,k5]。。。我试图理解你的代码,并试图修复它作为well@user3006475如果你认为自己已经找到了答案,那么你可以继续回答自己的问题。:)或者,如果您做了更改,还有其他问题,您可以更新原始问题。好的,我编辑我的问题…但我需要更多帮助来完成它。对于所有情况,我都尝试了所有机会,非常完美!谢谢@用户3006475很酷。你应该研究它,以确保你了解它是如何工作的。这与我们几天前在上做的insert_非常相似()。