我正试图将一个整数从十进制整数转换为基于基数4的字符串,但我的展开器不起作用,我不知道为什么或如何替换它。我也不能使用导入。请帮我解决这个问题。
dec2Base4 :: Int -> String
dec2Base4 = map i2c . reverse . unfoldr decomp
where
decomp n = if n == 0 then Nothing else Just(n `mod` 4, n `div` 4)
i2c i = if i == 0 then '0' else if i == 1 then '1' else if i == 2 then '2' else '3'
示例:dec2Base4 10-> "22"
您的代码基本上还可以,但需要从Data.List
包导入unfoldr
函数。
事实上,您被禁止使用import
子句,这可能只是意味着的函数希望您使用纯递归。
基于递归的解决方案:
不幸的是,递归自然会首先产生最低有效位(最右边的数字(,因为这个最右边的位数本质上是mod n 4
。您必须使用reverse
函数来纠正这一点,就像在基于库的代码中一样。
例如,在没有任何非Prelude库函数的帮助下,dec2Base4
函数可以这样编写:
dec2Base4 :: Int -> String
dec2Base4 n
| (n < 0) = '-' : (reverse (auxStr (-n)))
| (n == 0) = "0"
| otherwise = reverse (auxStr n) -- when n > 0
where
i2c i = "0123" !! i
auxStr 0 = ""
auxStr n = let (q,r) = (divMod n 4) in (i2c r) : (auxStr q)
测试代码:
unitTest :: Int -> IO ()
unitTest n = do
let res = dec2Base4 n
putStrLn $ "Result for " ++ (show n) ++ " is: " ++ res
main = do
let testList = [0,11,2051,-2051]
mapM_ unitTest testList
测试程序输出:
Result for 0 is: 0
Result for 11 is: 23
Result for 2051 is: 200003
Result for -2051 is: -200003