我正在寻找一种使用尾递归将十六进制更改为整数的方法。到目前为止,我只尝试了常规原始递归的可怕实现,我甚至没有接近。非常沮丧。甚至尾递归的例子也会有所帮助并且非常感激。对于这种实现,我不太了解它。
示例:
"005" -> 5
"1E" -> 30
限制:如果可能或者尾递归,不能使用import或if,then,else等,必须使用递归。
我尝试递归。
hexToInteger :: String -> Integer
|(x:xs) = [] = []
|x == 0 = hexToInteger xs
|otherwise = addition x + hexToInteger xs
addition :: String -> Integer
addition x
|--something to check what position we're dealing with and what hex value.
|--Return the Integer value
答案 0 :(得分:9)
通常,对于尾递归函数,您需要一个累加器参数 - 具有纯度,否则结果只能取决于达到的基本情况。所以你需要一个辅助函数,也可以使用一个累加器参数,并用累加器的初始值调用它,
hexToInteger :: String -> Integer
hexToInteger string = hexToIntegerHelper initialAccumulator string
你必须找出
例如,reverse
的尾递归实现是
reverse :: [a] -> [a]
reverse xs = reverseHelper [] xs
reverseHelper :: [a] -> [a] -> [a]
reverseHelper accumulator [] = accumulator
reverseHelper accumulator (x:xs) = reverseHelper (x:accumulator) xs
和尾递归因子(捏造负面论证的情况)
factorial :: Integer -> Integer
factorial n = factorialHelper 1 n
factorialHelper :: Integer -> Integer -> Integer
factorialHelper accumulator n
| n < 2 = accumulator
| otherwise = factorialHelper (n*accumulator) (n-1)
所以你可以看到hexToIntegerHelper
,
hexToIntegerHelper :: Integer -> String -> Integer
hexToIntegerHelper accumulator "" = accumulator
hexToIntegerHelper accumulator (d:ds) = hexToIntegerHelper (newAccumulatorFrom accumulator d) ds
问题是如何从旧的累加器和十六进制数字(以及初始累加器应该是什么)计算新的累加器。
更新累加器,
digitToInt :: Char -> Int
来自Data.Char
的可能很有用,可以处理所有十六进制数字。但是,它不会返回所需的类型,因此您需要使用fromIntegral
或toInteger
将Int
转换为Integer
。
答案 1 :(得分:2)
这里有两个递归函数,虽然已经向我指出它们不是尾递归的。也许他们可以帮助你实现目标。
hexToInteger :: String -> Integer
hexToInteger [] = 0
hexToInteger str =
fromIntegral z + 16 * hexToInteger (init str)
where z = let y = last str
in if y >= 'A' && y <= 'Z'
then fromEnum y - 55
else if y >= 'a' && y <= 'z'
then fromEnum y - 87
else fromEnum y - 48
hexToInteger :: String -> Integer
hexToInteger [] = 0
hexToInteger str =
z + 16 * hexToInteger (init str)
where z = case last str of
'0' -> 0
'1' -> 1
'2' -> 2
'3' -> 3
'4' -> 4
'5' -> 5
'6' -> 6
'7' -> 7
'8' -> 8
'9' -> 9
'A' -> 10
'B' -> 11
'C' -> 12
'D' -> 13
'E' -> 14
'F' -> 15
'a' -> 10
'b' -> 11
'c' -> 12
'd' -> 13
'e' -> 14
'f' -> 15
otherwise -> 0
答案 2 :(得分:0)
我们可以用与在纸上转换十六进制字符串相同的方式来实现:将输出初始化为0,然后从左到右读取字符串,每次将结果乘以16并添加新的数字。
使用初始化为0的累加器参数创建并调用私有函数:
hex2int s = hex2int' s 0
where
递归的基本情况是使用一个空字符串并返回累加器:
hex2int' "" n = n
递归情况采用字符串的第一个字符并相应地增加累加器。
hex2int' (c:s) n = hex2int' s ((n * 16) + (hexDigit2int c))
hexDigit2int
是一个简单的查找。
hexDigit2int c
| c == "0" = 0
...
| c == "f" = 15