我想解决一个简单的序言中的问题,但我不能够解决这个问题。 从列表中需要创建给出从我的下一个元素给出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