簡體   English   中英

在給定數字N的列表中刪除一個子列表,該數字表示連續的元素PROLOG

[英]Remove a sublist inside a list given a number N which indicates consecutive elements PROLOG

我正在嘗試解決Prolog練習。 它說,如果F是從I刪除元素數量(如N從位置P開始)的結果,則它起作用。我也有一些基本情況需要解決:

  • 如果起始位置(P)大於初始列表(I)的長度,則得到I。
  • 如果要刪除的元素數量(N)大於給定位置(P)中列表中元素的數量,它將刪除所有元素,直到最后,給出a
    結果為空列表。
  • 如果要刪除的元素數量(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.

尼古拉斯有正確的想法。 這是一個更正的版本:

% 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( 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.
  .

或者您可以將其分解為較小的問題,列出以下內容。 我們創建一個輔助謂詞( partition/4 ),該謂詞將一個列表最多分為指定長度和后綴(由剩余的內容組成)的前綴。

其余的很容易:我們調用partition/4前綴來獲取要保留的前綴及其剩余部分,然后將剩余部分划分為其前綴,我們要丟棄的元素及其后綴,我們想要保留的尾元素,然后在想要保留的后綴后面加上我們想要保留的前綴,從而得到結果列表。

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.
  .

正如他們所說,有多種方法可以做到這一點。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM