我正在使用歐幾里得演算法來計算 GCD(M,N),這是兩個整數 M 和 N 的最大公約數。
雖然這段代碼運行良好,但我覺得用 max、min 和 abs 為兩個變數(a、b)包裝它有點麻煩。
- 任何人都可以提出一種更好的方法來使代碼不那么冗長嗎?
- 我發現內置的 gcd 型別被定義為 gcd :: Integer a => a -> a -> a,但我不能簡單地使用它。為了重用型別定義,我需要更改什么?
gcd2 :: Int -> Int -> Int
gcd2 a b =
let x = max (abs a) (abs b)
y = min (abs a) (abs b)
in if (y == 0) || (x == y && x > 0)
then x
else gcd2 y (x-y)
好吧,受chi的啟發,我將代碼更改如下。
gcd3 :: Int -> Int -> Int
gcd3 a b | a < 0 = gcd3 (-a) b
| b < 0 = gcd3 a (-b)
| b > a = gcd3 b a
| b == a || b == 0 = a
| otherwise = gcd3 b (a-b)
這是我能做的最好的。:)
uj5u.com熱心網友回復:
你可以看看它是如何在 base 中實作的:
gcd :: (Integral a) => a -> a -> a
gcd x y = gcd' (abs x) (abs y)
where gcd' a 0 = a
gcd' a b = gcd' b (a `rem` b)
uj5u.com熱心網友回復:
正如 chi 在他的回答中所建議的那樣,為了避免在每個遞回步驟中使用 abs,我將定義一個 GCD 本地函式,您可以在其中傳遞引數的絕對值。這樣實作非常簡單:
gcd :: Int -> Int -> Int
gcd a b = gcd' (abs a) (abs b)
where gcd' a 0 = a
gcd' a b = gcd' b (a `mod` b)
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/482694.html
標籤:哈斯克尔
