跳过Prolog列表中的N个元素

时间:2016-09-24 19:45:29

标签: recursion prolog

我是Prolog的新手并且参加了这次练习。问题是要求定义谓词

everyNth(N, List1, List2)

这样List2包含第一个项目,后面是List1的第一个项目之后的每个第N个元素项目。

提示是使用追加和长度。

例如,

everyNth (3, [1,2,3,4,5,6,7], List2).
List2 = [1,4,7].

everyNth (2, [1,2,3,4,5,6], List2).
List2 = [1,3,5].

我以这种方式解决了这个问题,到目前为止,这就是我所拥有的: 不确定如果我朝着正确的方向前进。

 everyNth(N, [], L1).
 everyNth(N, [H|NL], RL) :-
    N > 0,length(NL,N),append(H, NL, RL),everyNth(N,NL,RL). 

任何建议或提示都会非常有用!

感谢。

2 个答案:

答案 0 :(得分:2)

我提出以下解决方案

everyNth(_, _, [], []).

everyNth(N, N, [H | Ti], [H | To]) :-
  everyNth(N, 1, Ti, To).

everyNth(N, C, [_ | Ti], Lo) :-
  C < N,
  Cp1 is C+1,
  everyNth(N, Cp1, Ti, Lo).

everyNth(N, Li, Lo) :-
  everyNth(N, N, Li, Lo).

我认为你需要两个使用两个数字:第一个是N并且是固定的;第二个,C是一个以1开头,到达N并从1重新开始的编码;等等。因此everyNth/3子句只调用everyNth/4版本。使用N作为计数器调用它来复制输入列表的第一个元素。

C等于N(第二everyNth/4)时,您将输入列表的标题(H)复制为输出列表的标题;否则你扔掉它。

您需要一个终端子句(everyNth(_, _, [], []).)来初始化输出列表(到[])。

答案 1 :(得分:1)

尝试这样的事情。

first_and_every_nth_item( _ , []     , []     ) .  % empty list? Easy!
first_and_every_nth_item( N , [X|Xs] , [X|Ys] ) :- % take the first item
  every_nth_item(1,N,Xs,[],Ys)                     % then take every nth item from the remainder.
  .

every_nth_item(_,_,[],Ts,Ys) :-      % if the source list is exhausted, we're good.
  reverse(Ts,Ys)                     % just reverse the accumulator to get the result
  .                                  %
every_nth_item(N,M,[_|Xs],Ts,Ys) :-  % otherwise...
  N < M ,                            % - if N < M 
  N1 is N+1 ,                        % - increment N
  every_nth_item(N1,M,Xs,Ts,Ys)      % - and recurse down, discarding the head of the source list.
  .
 every_nth_item(N,M,[X|Xs],Ts,Ys) :- % otherwise
   N = M ,                           % - if N = M
   T1 = [X|Ts]                       % - prepend X to the accumulator
   every_nth_item(1,M,Xs,T1,Ys)      % - recurse down with the count restarted
   .                                 %