5

宿題の割り当てでは、再帰関数(必要な数のヘルパーメソッドを使用)を使用して、16進文字列を基数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  

ただし、これでは正しい結果が得られません。誰かがこれを行う正しい方法を知っていますか?

4

3 に答える 3

6

あなたは本当に近いです。あなたのエラーはこの行にあります:

    | length hxStr /= 0 = (hexChar(last(hxStr)))+(10*parseHex(init(hxStr)))

なぜ10を掛けているのか考えてみてください。覚えておいてください...16進数は基数16です。

于 2013-02-18T04:29:28.550 に答える
5

正しい答えが得られたので、スタイルを検討する必要があります。パターンマッチングを使用すると、これはすでに明確に見えます。

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))

andの代わりにandhStrが必要なため、すぐにパターンマッチングを実行できないのは残念です。しかし、あなたはその使用とヘルパーを軽減することができます:initlastheadtailreverse

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?
于 2013-02-18T10:35:38.643 に答える
4

問題が解決した後、これを書くためのより短い方法がここにあります:

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
于 2013-02-18T12:49:22.493 に答える