Prolog 如何确定列表中两个数字的和
试图确定列表中的两个数字是否等于给定值Prolog 如何确定列表中两个数字的和,prolog,Prolog,试图确定列表中的两个数字是否等于给定值 sum([ ],0). %Pretty sure this makes the list(?) sum([H|T],Sum) :- sum(T, Temp), Sum is Temp + H. %recursively adds the numbers %maybe my base case is off 我已经阅读了swi prolog文档中的许多问题和大多数lists.pl。我可以确定如何确定列表中所有项的总和是否等于给定值,但不能确定其中任何两项是
sum([ ],0). %Pretty sure this makes the list(?)
sum([H|T],Sum) :- sum(T, Temp), Sum is Temp + H. %recursively adds the numbers
%maybe my base case is off
我已经阅读了swi prolog文档中的许多问题和大多数lists.pl。我可以确定如何确定列表中所有项的总和是否等于给定值,但不能确定其中任何两项是否等于给定值
sum([ ],0). %Pretty sure this makes the list(?)
sum([H|T],Sum) :- sum(T, Temp), Sum is Temp + H. %recursively adds the numbers
%maybe my base case is off
返回true,因为列表项的总和为10,但是
?- sum([1,2,3,4], 6).
返回false,我需要它返回true,因为4+2=6。append/3是分解列表的朋友
试着这样做:
sum_of_2_items(L,N) :-
take2( L, X, Y ),
N =:= X + Y
.
take2( L , X , Y ) :-
append( Pfx, [X|Sfx], L ),
gety( Pfx, Sfx , Y )
.
gety( L, _, Y ) :- gety( L, Y ).
gety( _, L, Y ) :- gety( L, Y ).
gety( [Y|_], Y ).
gety( [_|Ys], Y ) :- gety( Ys, Y ).
在分解列表时,append/3是您的朋友
试着这样做:
sum_of_2_items(L,N) :-
take2( L, X, Y ),
N =:= X + Y
.
take2( L , X , Y ) :-
append( Pfx, [X|Sfx], L ),
gety( Pfx, Sfx , Y )
.
gety( L, _, Y ) :- gety( L, Y ).
gety( _, L, Y ) :- gety( L, Y ).
gety( [Y|_], Y ).
gety( [_|Ys], Y ) :- gety( Ys, Y ).
这方面的教科书谓词是select/3。它是列表、列表中的元素和列表其余部分之间的真实关系
?- select(X, [1,2,3,4], Rest).
X = 1,
Rest = [2, 3, 4] ;
X = 2,
Rest = [1, 3, 4] ;
X = 3,
Rest = [1, 2, 4] ;
X = 4,
Rest = [1, 2, 3].
所以你只需使用它两次:
sum_of_two(List, Sum) :-
select(X, List, L0),
select(Y, L0, _),
plus(X, Y, Sum).
这方面的教科书谓词是select/3。它是列表、列表中的元素和列表其余部分之间的真实关系
?- select(X, [1,2,3,4], Rest).
X = 1,
Rest = [2, 3, 4] ;
X = 2,
Rest = [1, 3, 4] ;
X = 3,
Rest = [1, 2, 4] ;
X = 4,
Rest = [1, 2, 3].
所以你只需使用它两次:
sum_of_two(List, Sum) :-
select(X, List, L0),
select(Y, L0, _),
plus(X, Y, Sum).
您可以更一般地检查一个数字是否是列表中的数字之和 有两种基本情况: N是列表中的一员
sum(L, N) :-
member(L, N).
N可以是两个数字的总和:
sum(L, N) :-
select(A, L, L1),
select(B, L1, _),
N is A+B.
现在一般情况是:
sum(L, N):-
select(A, L, L1),
N1 is N-A,
N1 >= 0,
sum(L1, N1).
请注意,此代码仅适用于正数
可能有很多解决方案,因此我们可以检查是否有一个具有once/1的解决方案。
因此:
您可以更一般地检查一个数字是否是列表中的数字之和 有两种基本情况: N是列表中的一员
sum(L, N) :-
member(L, N).
N可以是两个数字的总和:
sum(L, N) :-
select(A, L, L1),
select(B, L1, _),
N is A+B.
现在一般情况是:
sum(L, N):-
select(A, L, L1),
N1 is N-A,
N1 >= 0,
sum(L1, N1).
请注意,此代码仅适用于正数
可能有很多解决方案,因此我们可以检查是否有一个具有once/1的解决方案。
因此:
显然,DCG的情况如下:
sum_of_2_items(Xs, N) :-
phrase(( ..., [A], ..., [B], ...), Xs),
N is A+B.
... --> [] | [_], ... .
或者,最低限度地提高效率:
sum_of_2_items(Xs, N) :-
phrase(( ..., [A], ..., [B], {N is A+B}, ...), Xs).
显然,DCG的情况如下:
sum_of_2_items(Xs, N) :-
phrase(( ..., [A], ..., [B], ...), Xs),
N is A+B.
... --> [] | [_], ... .
或者,最低限度地提高效率:
sum_of_2_items(Xs, N) :-
phrase(( ..., [A], ..., [B], {N is A+B}, ...), Xs).
或者甚至取2个有序的XsYs,X,Y:-append_u1;,[X | Ys],XsYs,append_1;,[Y | 1;,Ys.@jsf。。。据我所知,append_uuu,[X | Ys],L与selectX完全相同,L,Ys?@User9213不完全相同,append Ys是X之后的列表的其余部分,select是没有X的整个列表。这就是为什么基于select的解决方案效率有点低,他们按不同的顺序看每个值对两次。@jschimpf我现在明白了¸谢谢!因此,基本上使用append可以在拾取的图元上添加位置约束,这绝对有用。如果你不写评论作为回答,我会写-@用户9213继续;或者甚至取2个有序的XsYs,X,Y:-append_u1;,[X | Ys],XsYs,append_1;,[Y | 1;,Ys.@jsf。。。据我所知,append_uuu,[X | Ys],L与selectX完全相同,L,Ys?@User9213不完全相同,append Ys是X之后的列表的其余部分,select是没有X的整个列表。这就是为什么基于select的解决方案效率有点低,他们按不同的顺序看每个值对两次。@jschimpf我现在明白了¸谢谢!因此,基本上使用append可以在拾取的图元上添加位置约束,这绝对有用。如果你不写评论作为回答,我会写-@用户9213继续;