簡體   English   中英

Haskell:遞歸地將十六進制字符串轉換為整數?

[英]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上進行模式匹配,因為你需要initlast而不是headtail 但是你可以使用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM