[英]Haskell: recursively convert hex string to integer?
對於我的家庭作業,我需要使用遞歸函數將十六進制字符串轉換為基數為10的整數(根據需要使用盡可能多的輔助方法)。
這是我到目前為止所得到的:
-- Question 1, part (c):
hexChar :: Char -> Integer
hexChar ch
| ch == '0' = 0
| ch == '1' = 1
| ch == '2' = 2
| ch == '3' = 3
| ch == '4' = 4
| ch == '5' = 5
| ch == '6' = 6
| ch == '7' = 7
| ch == '8' = 8
| ch == '9' = 9
| ch == 'A' = 10
| ch == 'B' = 11
| ch == 'C' = 12
| ch == 'D' = 13
| ch == 'E' = 14
| ch == 'F' = 15
| otherwise = 0
parseHex :: String -> Integer
parseHex hxStr
| length hxStr /= 0 = (hexChar(last(hxStr)))+(10*parseHex(init(hxStr)))
| otherwise = 0
但是,這不會產生正確的結果。 有誰知道這樣做的正確方法?
你真的很親密。 你的錯誤是在這一行:
| length hxStr /= 0 = (hexChar(last(hxStr)))+(10*parseHex(init(hxStr)))
想想你為什么乘以10.記住......十六進制是16的基數。
既然你得到了正確的答案,你應該考慮這種風格。 使用模式匹配,這看起來更清晰:
parseHex :: String -> Integer
parseHex [] = 0
parseHex hxStr = (hexChar(last(hxStr)))+(16*parseHex(init(hxStr)))
而且它也更有效率,因為您不需要在每次遞歸調用時評估length hxStr
(即O(N))以決定適用哪種情況。 總運行時間從O(N ** 2)變為O(N)。
當你刪掉一些括號時,它看起來會更好,正如groovy建議的那樣:
parseHex :: String -> Integer
parseHex [] = 0
parseHex hxStr = hexChar (last hxStr) + 16 * parseHex (init hxStr))
不幸的是你不能立即在hStr
上進行模式匹配,因為你需要init
和last
而不是head
和tail
。 但是你可以使用reverse
和helper來減輕這種影響:
parseHex :: String -> Integer
parseHex hxStr = go (reverse hxStr)
where go [] = 0
go (x:xs) = hexChar x + 16 * parseHex xs
最后一個可能僅僅是品味問題。 hexChar
也變短了:
hexChar '0' = 0
hexChar '1' = 1
... -- other cases here
hexChar _ = 0 -- 'otherwise' case; maybe throw an error instead?
問題解決后,這里寫一個更簡短的方法:
import Data.List
import Data.Maybe
hexChar ch = fromMaybe (error $ "illegal char " ++ [ch]) $
elemIndex ch "0123456789ABCDEF"
parseHex hex = foldl' f 0 hex where
f n c = 16*n + hexChar c
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.