我试图实现对数算法,但似乎是在一个循环中
loga_b :: Int -> Int -> Int
loga_b a b
| b == 1 = 0
| b == a = 1
| otherwise = 1 + loga_b (b `div` a) b
答案 0 :(得分:4)
你在最后一种情况下切换了参数 - 试试这个:
loga_b :: Int -> Int -> Int
loga_b a b
| b == 1 = 0
| b == a = 1
| otherwise = 1 + loga_b a (b `div` a)
的示例:
λ> loga_b 2 8
3
λ> loga_b 2 17
4
你真的不需要第二种情况:
loga_b :: Int -> Int -> Int
loga_b a b
| b == 1 = 0
| otherwise = 1 + loga_b a (b `div` a)
如果b == a
,那么最后一个案例将评估为相同的1
:
1 + loga_b a (a `div` a)
= 1 + loga_b a 1
= 1 + 0
= 1
正如Sassa所说,这是一个部分功能,我不确定你是如何正确修复的,但我认为这应该没问题:
loga_b :: Int -> Int -> Int
loga_b a b
| b < 0 || a < 0 = signum a * signum b * loga_b (abs a) (abs b)
| b < a = 0
| b >= a = 1 + loga_b a (b `div` a)
注意这会为负数我知道提供明智的行为 - 但我确定OP是否真的需要它,他可以自己思考所有案例;)