Euclid算法使用直到

时间:2014-04-25 15:27:00

标签: algorithm haskell

我是Haskell的初学者,现在开始学习折叠,而不是在大学,第一年。

我现在面临的一个问题是使用until函数定义Euclid的算法。

这是Euclid的递归定义(编辑:只是为了展示euclid如何工作,我试图在没有递归的情况下定义euclid。只是使用直到):

gcd a b = if b == 0 then a else gcd b (a `mod` b)

以下是我使用的内容:

gcd a b = until (==0) (mod a ) b

显然这没有任何意义,因为它总是会返回0,因为这是我的停止点,而不是打印b == 0时的值。我不知道如何获得a的价值。

感谢任何帮助。 提前谢谢你们。

2 个答案:

答案 0 :(得分:4)

提示:

现在

until :: (a -> Bool) -> (a -> a) -> a -> a

所以我们需要一个可以反复应用的函数,直到条件成立,但我们有两个数字ab,那么我们怎么做呢?

解决方案是将两个数字合并为一个值(a,b),因此请以这种方式考虑gcd

uncurriedGCD (a,b) = if b == 0 then (a,a) else uncurriedGCD (b,a `mod` b) 

现在你可以制作两个功能,next& check并将其与until一起使用。

until的助手:

next (a,b) = (b,a `mod` b)
check (a,b) = b == 0

这意味着我们现在可以使用uncurriedGCD编写until

答案:

例如:

ghci> until check next (6,4)
(2,0)
ghci> until check next (12,18)
(6,0)

所以我们可以定义:

gcd a b = c where (c,_) = until check next (a,b)

,并提供:

ghci> gcd 20 44
4
ghci> gcd 60 108
12

答案 1 :(得分:2)

欧几里德算法所说的是:对于(a, b),计算(b, mod a b)直到(新的)b等于零。这可以直接转换为使用until的实现,如下所示:

myGcd a b = until (\(x, y) -> y == 0) (\(x, y) -> (y, x `mod` y)) (a, b)