在尝试解决以下练习时......
定义函数
binaryDigits
,它接收一个Integer和 返回以二进制形式写入这样的数字所需的位数 代码。
...我发现自己认为通过递归调用函数binaryDigits
来解决这个问题是不可能的,因为它收到的唯一变量是实际数字
我之所以这样说,是因为该网站声称虽然它运行的测试成功了,但我并没有在函数binaryDigits
中使用递归。
所以如果我甚至不能告诉我多少次调用它,我怎么能想到递归地调用这个函数(并且假设被调用的次数表示它代表了多少个二进制数字那个数字)。
这就是我的想法:请注意我使用递归但在辅助函数中返回二进制数字表示的十进制值列表当该列表的总和是大于收到的数字:
double = (2*)
listOfBinaryDigits list num | num > (sum list) = listOfBinaryDigits ([double(head list)]++list) num
| otherwise = list
binaryDigits num = length (listOfBinaryDigits [1] num)
答案 0 :(得分:4)
这是一个"迭代"溶液:
binaryDigits = length . takeWhile (not . (==0)) . iterate (`div` 2)
您也可以通过递归重新定义它,直到您触及底部并在返回的路上加总长度。这将是一个很好的练习,所以我把解决方案留在了剧透你的
binaryDigits 0 = 0; binaryDigits x = 1 + binaryDigits (div x 2)
答案 1 :(得分:0)
无需递归或迭代。你也许可以使用base 2对数,如下所示;
binaryDigits :: (Floating a, Integral c, RealFrac a) => a -> c
binaryDigits n | n == 0 = 1
| otherwise = 1 + (floor . logBase 2 $ n)
> binaryDigits 1453
> 11