代码在这里,当我调用numberOf 3或numberOf整数> 2我得到此错误ERROR - C堆栈溢出。我的代码应该将2 ^(n-2)(2 ^ n)-1之间的数字更改为n> 2到二进制并检查是否有连续的0。如果有不计数,如果没有+1。
numberOf :: Integer -> Integer
numberOf i = worker i
worker :: Integer -> Integer
worker i
| (abs i) == 0 = 0
| (abs i) == 1 = 2
| (abs i) == 2 = 3
| otherwise = calculat (2^((abs i)-2)) ((2^(abs i))-2)
calculat :: Integer -> Integer -> Integer
calculat ab bis
| ab == bis && (checker(toBin ab)) == True = 1
| ab < bis && (checker(toBin ab)) == True = 1 + (calculat (ab+1) bis)
| otherwise = 0 + (calculat (ab+1) bis)
checker :: [Integer] -> Bool
checker list
| list == [] = True
| 0 == head list && (0 == head(tail list)) = False
| otherwise = checker ( tail list)
toBin :: Integer -> [Integer]
toBin n
| n ==0 = [0]
| n ==1 = [1]
| n `mod` 2 == 0 = toBin (n `div` 2) ++ [0]
| otherwise = toBin (n `div` 2) ++ [1]
测试:
numberOf 3答案:(5)
numberOf 5(13)
numberOf 10(144)
numberOf(-5)(13)
答案 0 :(得分:5)
问题在于您对calculat
的定义。您有ab == bis
和ab < bis
的案例,但您致电calculat
的唯一地方来自worker
,其参数为2^(abs i - 1)
和2^(abs i - 2)
。由于第一个数字(ab
)将始终大于第二个数字(bis
),因此检查ab < bis
非常愚蠢。在您的情况下,然后递增ab
,确保此函数永远不会终止。你的意思是otherwise = calculat ab (bis + 1)
吗?
你也可以大大清理你的代码,有很多地方你做得很辛苦,或者添加了不必要的混乱:
-- Remove worker, having it separate from numberOf was pointless
numberOf :: Integer -> Integer
numberOf i
| i' == 0 = 0
| i' == 1 = 2
| i' == 2 = 3
-- Lots of unneeded parentheses
| otherwise = calculat (2 ^ (i' - 1)) (2 ^ i' - 2)
-- Avoid writing the same expression over and over again
-- define a local name for `abs i`
where i' = abs i
calculat :: Integer -> Integer -> Integer
calculat ab bis
-- Remove unneeded parens
-- Don't need to compare a boolean to True, just use it already
| ab == bis && checker (toBin ab) = 1
| ab < bis && checker (toBin ab) = 1 + calculat (ab + 1) bis
-- 0 + something == something, don't perform unnecessary operations
| otherwise = calculat (ab + 1) bis
-- Pattern matching in this function cleans it up a lot and prevents
-- errors from calling head on an empty list
checker :: [Integer] -> Bool
checker [] = True
checker (0:0:_) = False
checker (_:xs) = checker xs
-- Again, pattern matching can clean things up, and I find an in-line
-- if statement to be more expressive than a guard.
toBin :: Integer -> [Integer]
toBin 0 = [0]
toBin 1 = [1]
toBin n = toBin (n `div` 2) ++ (if even n then [0] else [1])
答案 1 :(得分:0)
在计算中,如果ab == bis但检查器返回false,则无法从函数返回。
怎么样:
| ab >= bis && (checker(toBin ab)) == True = 1
| ab < bis && (checker(toBin ab)) == True = 1 + (calculat (ab+1) bis)
| otherwise = 0 + (calculat (ab+1) bis)
| ab >= bis = 0
| ab < bis == True = 0 + (calculat (ab+1) bis)
| otherwise = 0 + (calculat (ab+1) bis)