如何在prolog中修剪List中的前N个元素

时间:2014-12-15 08:23:06

标签: list prolog trim concat

如何使用conc操作编写一个prolog程序来修剪prolog中List的前N个元素。

trim(L1,N,L2) which is true if L2 contains the first N elements of L1 

请有人帮助我。

这是我的答案,是否正确?

trim(L1, N, L2):- conc(L2,T,L1), length(L2,N),length(L1,N2), N2>= N

1 个答案:

答案 0 :(得分:4)

简易解决方案使用length/2append/3,这些行:

trim(L,N,S) :-    % to trim N elements from a list
  length(P,N) ,   % - generate an unbound prefix list of the desired length
  append(P,S,L) . % - and use append/3 to get the desired suffix.

请注意,订单并不重要。这也可行:

trim(L,N,S) :-    % to trim N elements from a list
  append(P,S,L) , % - split L into a prefix and suffix
  length(P,N) .   % - succeed if the prefix is of the desired length

我想你的导师希望你找出一个/递归的解决方案。有人可能会注意到,从列表左端修剪项目的算法非常简单:

  • 点击列表,直到您访问过N元素。
  • 一旦你做完了,剩下的就是想要的结果。

这导致了一个简单的解决方案:

trim( L     , 0 , L ) .  % Trimming zero elements from a list yields the original, unchanged list
trim( [H|T] , N , R ) :- % Otherwise,
  N > 0 ,                % - assuming N is greater than zero
  N1 is N-1 ,            % - we decrement N
  trim( T , N1 , R )     % - and recurse down, discarding the head of the list.
  .                      % That's about all there is too it.

如果你想变得迂腐,可以强制执行一个约束,列表实际上应该是一个列表(或者至少是列表),如:

trim( []    , 0 , []    ) .  % Trimming zero elements from the empty list yields the empty list
trim( [H|T] , 0 , [H|T] ) .  % Trimming zero elements from a non-empty list yields the same list  
trim( [H|T] , N , R     ) :- % Otherwise,
  N > 0 ,                    % - given that N is greater than zero
  N1 is N-1 ,                % - we decrement N
  trim( T , N1 , R )         % - and recurse down, discarding the head of the list.
  .                          % That's about all there is to it.

请注意

之类的内容
trim( [a,b,c] , 5 , R ) .

将失败:看看你是否可以通过R = []弄清楚如何使上述成功。提示:这并不难。

编辑注意:如果您确实想要获取列表的前N个元素,那就不再困难了:

prefix_of(L,N,P) :-
  append(P,_,L) ,
  length(P,N)
  .

或者,滚动自己,你可以这样做:

prefix_of( _      , 0 , []     ) .  % once we've counted down to zero, close the result list and succeed.
prefix_of( [X|Xs] , N , [X|Ys] ) :- % otherwise,
  N > 1 ,                           % - given that N is greater than zero,
  N1 is N-1 ,                       % - decrement N
  prefix_of( Xs , N1 , Ys )         % - and recurse down, with X prepended to the resullt list.
  .                                 % Again, that's about all there is to it.