List Prolog中奇数的偶和积
我有一个数字列表,我需要计算列表的偶数和同一列表的奇数的乘积之和。我是Prolog新手,到目前为止我的搜索没有成功。有人能帮我解决吗List Prolog中奇数的偶和积,list,prolog,clpfd,meta-predicate,List,Prolog,Clpfd,Meta Predicate,我有一个数字列表,我需要计算列表的偶数和同一列表的奇数的乘积之和。我是Prolog新手,到目前为止我的搜索没有成功。有人能帮我解决吗 l_奇偶([])。 l|u奇偶([H|T],奇数[H|Etail]):- H rem 2=:=0, 分裂(T,奇数,Etail)。 l|u奇偶([H|T],[H|Otail],偶数):- H rem 2=:=1, 拆分(T、Otail、偶数)。 下面是一个关于列表中偶数总和的建议: 偶数(X):- Y是mod(X,2),%使用“is”计算为数字 Y=:=0。 奇数
l_奇偶([])。
l|u奇偶([H|T],奇数[H|Etail]):-
H rem 2=:=0,
分裂(T,奇数,Etail)。
l|u奇偶([H|T],[H|Otail],偶数):-
H rem 2=:=1,
拆分(T、Otail、偶数)。
下面是一个关于列表中偶数总和的建议:
偶数(X):-
Y是mod(X,2),%使用“is”计算为数字
Y=:=0。
奇数(X):-%使用偶数
Y是X+1,
偶数(Y)。
和偶数(0,[])。%空列表的和为零
和偶数(X[H | T]):-
偶数(H),
求和偶数(Y,T),
X是Y+H。
和偶数(X[H | T]):-
奇数(H),
求和偶数(X,T)。%忽略奇数
注意:我的Prolog已被氧化,因此可能有更好的解决方案。:-)
注意:天哪!似乎没有Prolog支持语法突出显示(请参阅),所以我使用了Erlang语法。
哈,真的很管用。:-)
在GNU Prolog中运行一些查询,我得到:
|?-sum_偶数(X,[])。
X=0?
对
|?-sum_偶数(X,[2])。
X=2?
对
|?-sum_偶数(X,[3])。
X=0?
对
|-和_偶数(X[5,4,3,2,1,0])。
X=6?
对
这里应用的想法应该能让你想出所需的产品。未经测试
sum_odd_product_even([], S, P, S, P).
sum_odd_product_even([H|T], S0, P0, S, P) :-
S1 is S0 + H,
sum_even_product_odd(T, S1, P0, S, P).
sum_even_product_odd([], S, P, S, P).
sum_even_product_odd([H|T], S0, P0, S, P) :-
P1 is P0 * H,
sum_odd_product_even(T, S0, P1, S, P).
sum_odd_product_even(L, S, P) :-
sum_odd_product_even(L, 0, 1, S, P).
sum_even_product_odd(L, S, P) :-
sum_even_product_odd(L, 0, 1, S, P).
它不应该比
%
% invoke the worker predicate with the accumulators seeded appropriately.
%
odds_and_evens( [O] , P , S ) :- odds_and_evens( [] , O , 0 , P , S ) .
odds_and_evens( [O,E|Ns] , P , S ) :- odds_and_evens( Ns , O , E , P , S ) .
odds_and_evens( [] , P , S , P , S ) . % if the list is exhausted, we're done.
odds_and_evens( [O] , X , X , P , S ) :- % if it's a single element list, we've only an odd element...
P is X*O , % - compute it's product
. % - and we're done.
odds_and_evens( [O,E|Ns] , X , Y , P , S ) :- % if the list is at least two elements in length'e both an odd and an even:
X1 is X*O , % - increment the odd accumulator
Y1 is Y+E , % - increment the even accumulator
odds_and_evens( Ns , X1 , Y1 , P , S ) % - recurse down (until it coalesces into one of the two special cases)
. % Easy!
使用
在foldl/4
的基础上,我们只需要定义一个折叠步骤:
sumprod_(Z,S0,S) :-
M #= Z mod 2,
rem_sumprod_(M,Z,S0,S).
rem_sumprod_(0,Z,S0-P,S-P) :-
S0 + Z #= S.
rem_sumprod_(1,Z,S-P0,S-P) :-
P0 * Z #= P.
让我们在列表上折叠sumprod\u3
l_odd_even(Zs,ProductOfOdds,SumOfEvens) :-
foldl(sumprod_,Zs,0-1,SumOfEvens-ProductOfOdds).
示例查询:
?- l_odd_even([1,2,3,4,5,6,7],Odd,Even).
Odd = 105,
Even = 12.
或者,我们可以使用和更简洁地定义
sumprod\u3
:
你能展示一下你已经尝试过的吗?首先,你需要尝试一下。我知道你对Prolog还不熟悉,但到目前为止你对Prolog了解多少?因为你处理的是一个数字列表,所以你需要操纵一个列表。你可以在谷歌上搜索“prolog列表处理”,并获得一些关于如何管理列表的好信息。首先,
[]
是一个空列表,[H | T]
是一个包含第一个元素H
的列表,列表的其余部分(尾部)是T
。这是我到目前为止的代码“l_奇偶([])。l_奇偶([H | T],奇数,[H | Etail:-((H rem 2)==0),split(T,奇数,Etail l)。l_奇偶([H | T],[H]:=1),split(T、Otail、偶数)我只是不知道如何实现这之后的和和和积,所以,零的积是1?@Boris:是的,乘法的中性元素。我不确定,但我想你得到的是奇偶位置的数的和和和积,但OP似乎在试图得到偶数和o的和和和积dd编号。
?- l_odd_even([1,2,3,4,5,6,7],Odd,Even).
Odd = 105,
Even = 12.
sumprod_(Z,S0-P0,S-P) :-
if_(zeven_t(Z), (S0+Z #= S, P0=P),
(P0*Z #= P, S0=S)).