如何解决将列表分成两部分
我正在尝试在序言中将列表分为2个。但是我对此仍然陌生,将不胜感激。
我的问题是:
实施子句select(N,L,R,S),从L中选择N个项目并将其放在R中,其余元素留在S中
这是我到目前为止尝试过的:
split(0,_L1,_L2,_L4).
split(X,[H|T],L1,T):-
X>0,X1 is X-1,split(X1,T,[H|L1],T).
当我尝试跑步时
split(2,[1,2,4,5],X,Y).
false
这是我得到的结果。我在做什么错了?
解决方法
如果X> 0,则fiscal_year
列表的第一个元素也必须是L
列表的第一个元素。例如,它应为:R
。如果我们希望保持这种关系,则必须在规则的 head 中表达它。
您的第二个子句应该看起来像这样:
split(1,[a | Rest],[a],Rest)
这可以很好地分割前缀,但是其余的还不正确:
split(X,[H|T],[H|L1],Rest) :-
X > 0,X1 is X - 1,split(X1,T,L1,Rest).
您需要重新考虑要拆分0个元素的情况。 ?- split(2,[1,2,4,5],R,S).
R = [1,2|S] ;
false.
的结果应该是什么?
最大的问题是构造/解构第三个参数的方式。
您缺少特殊情况。
大多数递归问题都有一些特殊情况,通常是终止情况,还有一个一般情况。这个问题有两种特殊情况。
一般情况很简单。您会在此处注意到,我们用[X|Pfx]
统一了第三个参数。这会将X
添加到左/前缀结果的开头,并为我们提供(可能未绑定的)尾部。尾巴递归传递下来。
partition( N,[X|Xs],[X|Pfx],Sfx ) :-
N > 0,N1 is N-1,partition( N1,Xs,Pfx,Sfx )
.
[您可能会注意到,随着我们的前进,我们正在第3个参数(前缀列表)中建立一个列表...但这不是合法列表:尾部可能没有约束。最后,我们会解决这个问题。
所以...这可以解决一般情况。但是,我们怎么知道什么时候完成?
一种特殊/终止情况是当源列表用尽时。如果在N
递减到0
之前发生了,那么我们就完成了。我们可以这样处理:
partition( _,[],[] ).
我们并不真正在意N
的值是什么,但是加强N >= 0
的约束可能很有用。这里发生的是,当源列表(第二个参数)用尽且为空列表时,我们(1)关闭前缀列表(第三个参数),并将后缀列表与空列表统一。
下一个特殊情况是N
最终减为零。不再复杂:
partition( 0,Sfx,Sfx ).
我们用后缀列表(第4个参数)统一源列表的其余内容,并用空列表关闭前缀列表。
剩下的特殊情况是当N
最终减为0
时。就这么简单。这是
partition( 0,Xs ).
将所有内容放在一起,您将得到:
partition( _,[] ).
partition( 0,Sfx ).
partition( N,Sfx ) :-
N > 0,Sfx ).
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。