创建从给定的指标,多种元素的列表子列表。 序言(Create a sublist from a

2019-10-19 03:53发布

我想解决一个简单的序言中的问题,但我不能够解决这个问题。 从列表中需要创建给出从我的下一个元素给出N.如果该指数大于名单lenght我会得到子列表为空更大的索引我,然后子列表。 如果N(元素的数量)比在列表中,我会得到所有从我直到最后的元素元素的其余部分更大。

在这里,我得到了任务的一个组成部分,我可以从我的下一个元素N.现在我要问关于转让的其他部分指数得到:

1)当I (指数)比列表的长度越长,我得在子列表空列表。

?- sublist([a,b,c,d],5,2,L)

L=[]

2)当N (下一页要素)比我们休息元素的数量更大,我需要把所有从该位置到结束的元素。

?- sublist([a,b,c,d],4,4,L)

L=[d]      

我已经有该代码是下一个,这一个是工作:

sublist([X|_],1,1,[X]).
sublist([],_,_,[]).% I use this one for the case bases
sublist([X|Xs],1,K,[X|Ys]):-
       K>1, 
       K1 is K-1,
       sublist(Xs,1,K1,Ys).
sublist([_|Xs],I,K,Ys):-
       I > 1, 
       I1 is I-1,
       sublist(Xs,I1,K,Ys).

Answer 1:

sublist([X|_], 1, 1, [X]).

这是一个很好的条款。 它说,开始从列表中取1长度为1的子表[X|_][X]

sublist([X|Xs], 1, K, [X|Ys]) :-
    K > 1, 
    K1 is K - 1,
    sublist(Xs, 1, K1, Ys).

这也是一个很好的条款。 它说,长度的子列表K起始于取自1 [X|Xs]的开头是X和具有尾部Ys其长度的子列表K-1从第一清单(尾部Xs )从1开始。

sublist([_|Xs], I, K, Ys) :-
    I > 1, 
    I1 is I - 1,
    K1 is K - 1,
    sublist(Xs, I1, K1, Ys).

这一条款有问题。 如果你有一个列表[_|Xs]并想利用长的子列表K开始在I (对I大于1),你把长的子表K-1从尾部开始位置I-1 现在的问题是: 为什么会子列表现在需要的长度K-1 这一条款的目的应该是减少的问题到你处理的起始索引的情况下1 ,然后让第二条走其余的工作。

然后在你所期望的行为的定义,你必须: 如果N(元素的数量)比在列表中,我会得到所有从我直到最后的元素元素的其余部分更大。 这种观点目前没有在任何条款。 基本情况是目前您其中特别要求的长度1产生长度为1的列表,您需要来处理,其中第一不胜枚举空的,但另一种情况基本情况条款第一条K可能仍然是任何值:

sublist([], ?, _, ?).

只是在填? 与一些逻辑。 :)



Answer 2:

只是为了显示如何不确定性内建像NTH1 / 3可以帮助...

sublist(List, From, Count, SubList) :-
    findall(E, (nth1(I, List, E), I >= From, I < From + Count), SubList).

编辑注释说,这个“一个班轮”实际上是比制作的子表/ 4少了很多有效的。

确实,

2 ?- N=1000000,length(L,N),time(sublist(L,N,1,V)).
% 3,000,014 inferences, 2.129 CPU in 2.134 seconds (100% CPU, 1409024 Lips)
N = 1000000,
L = [_G28, _G31, _G34, _G37, _G40, _G43, _G46, _G49, _G52|...],
V = [_G3000104].

3 ?- N=1000000,length(L,N),time(sublist(L,1,1,V)).
% 4,000,012 inferences, 2.549 CPU in 2.553 seconds (100% CPU, 1569076 Lips)
N = 1000000,
L = [_G28, _G31, _G34, _G37, _G40, _G43, _G46, _G49, _G52|...],
V = [_G3000104].

我要看看是否某种的findall“谓词中切可以解决这个问题,但它不太可能。 这一个是更好的:

sublist(List, From, Count, SubList) :-
    To is From + Count - 1,
    findall(E, (between(From, To, I), nth1(I, List, E)), SubList).

18 ?- N=1000000,length(L,N),time(sublist(L,3,3,V)).
% 28 inferences, 0.000 CPU in 0.000 seconds (93% CPU, 201437 Lips)
N = 1000000,
L = [_G682, _G685, _G688, _G691, _G694, _G697, _G700, _G703, _G706|...],
V = [_G3000762, _G3000759, _G3000756].


Answer 3:

这里有一个解决方案(虽然它可能不是你的教授想要什么):

sublist( Xs , Offset , Count , Ys ) :- %
  length(Prefix,Offset ) ,             % construct a list of variables of length 'offset'
  length(Ys,Count) ,                   % construct a list of variables of length 'count'
  append(Prefix,Suffix,Xs) ,           % strip the first first 'offset' items from the source list ,
  append(Ys,_,Suffix)                  % extract the first 'count' items from what's left.
  .                                    % easy!

这是一种方法,让序言的内置插件做的工作适合你。

下面是不使用任何内建的另一种方法。 这一次使用一个辅助谓词,简单地分割清单到指定长度的前缀和后缀,包括无论是遗留下来的。

sublist( Xs , Offset , Count , Ys ) :-
  split(Xs,Offset,_,X1) ,               % extract the first 'offset' items from the lsit and toss them
  split(X1,Count,Ys,_)                  % extract the first 'count' items from the remainder to get the result.
  .

split( []     , 0 , []     , []     ) .  % splitting a zero-length prefix from an empty list yields a zero-length prefix and a zero length suffix.
split( [X|Xs] , 0 , []     , [X|Xs] ) .  % splitting a zero-length prefix from a non-empty list yields a zero-length prefix and the non-empty list.
split( [X|Xs] , N , [X|Ps] , Qs     ) :- % Otherwise...
  N > 0 ,                                % - if the count is positive
  N1 is N-1 ,                            % - we decrement count
  split( Xs , N1 , Ps , Qs )             % - and recurse down, prepending the head of the source list to the prefix
  .                                      % Easy!


文章来源: Create a sublist from a list given an index and a number of elements. Prolog