5

末尾再帰を使用して 16 進数を整数に変更する方法を探しています。これまでのところ、通常のプリミティブ再帰のひどい実装を試しただけで、それに近づくことさえできませんでした。とてもイライラします。末尾再帰の例も役に立ち、非常に高く評価されます。この実装については十分に理解していません。

例:

  • "005" -> 5
  • "1E" -> 30

制限事項: インポートを使用できないか、可能であれば再帰または末尾再帰を使用して 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
4

3 に答える 3

2

ここに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
于 2013-02-17T23:46:01.970 に答える
0

これは、紙の上で 16 進数の文字列を変換するのと同じ方法で実装できます。出力を 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
于 2019-03-07T15:04:10.323 に答える