2017-01-19 37 views
-1

你好,我试图找到在Prolog中的数字列表的GCD,但我无法设法做到这一点。 你能帮忙吗?序言找到一个数字列表的GCD

我甚至没有接近,所以我不会分享我的任何工作到现在。 PP:在试图解决这个问题的过程中,我遇到了另一个我无法解决的问题,如果你能帮助解决这个问题,我将不胜感激。它找到两个数字的所有常见因数。

谢谢!

+0

感兴趣的:[RosettaCode - GCD - Prolog](http://rosettacode.org/wiki/Greatest_common_divisor#Prolog) –

+0

您可以搜索Prolog GCD的此站点。我相信你会找到一些东西。 – lurker

+2

您是否决定了如何计算GCD的一般算术策略?有几种方法可以独立于Prolog。 – lurker

回答

1

感谢Lurker! 我没有使用正确的算法。我想到找到两个数字的GCD,然后是结果和下一个GCD,但我不确定为什么我感到困惑,这是行不通的。

总之,这里是代码:

gcd(0,X,X):- X > 0, !. 
gcd(X,Y,Z):- X>=Y, X1 is X -Y, gcd(X1,Y,Z). 
gcd(X,Y,Z):- X<Y, X1 is Y-X, gcd(X1,X,Z). 
gcdL([H,H1|T],Z):-gcd(H,H1,X),gcdL([X|T],Z). 
gcdL([H1,H2],Z):-gcd(H1,H2,Z). 

而对于这里的好奇的是滞后的方法,我试图实现。我几乎在那里,脚本给出的第一个答案是正确的,但它仍然在回溯。无论如何,这是丑陋的,长期的,艰苦的和低效的:

minel([X],X). 
minel([H,H1|T],X):-H>H1,minel([H1|T],X). 
minel([H,H1|T],X):-H=<H1,minel([H|T],X). 
gcdL(L,X):-gcdL(L,X,1). 
gcdL(L,X,C):-minel(L,M),C<M,delAll(L,C),Temp is C,C1 is C + 1,gcdL(L,R,C1),X is max(Temp,R). 
gcdL(L,X,C):-minel(L,M),C1 is C + 1,C1=<M,gcdL(L,X,C1). 
gcdL(L,X,C):-minel(L,M),C=:=M,X is 1. 
delAll([T],X):- 0 is mod(T,X). 
delAll([H|T],X):- 0 is mod(H,X),delAll(T,X) 

注意:首先找到最合适的算法,然后尝试脚本的问题。

+1

如果你想更通用一些,你可以在'gcd/3'中添加一些子句,使其与负数一起工作。负数的GCD是这些数字的绝对值的GCD。 – lurker

+0

谢谢,如果我有空闲时间,我会鼓励。 –