2

给定一个 8 位二进制文​​件,我想得到它的 char 表示。例如:

[0,1,1,0,0,0,0,1] 我相信它是“a”的二进制表示。

提前致谢!

4

2 回答 2

5
import Data.Char

ord2chr :: [Int] -> Char
ord2chr = chr . foldl (\a b -> 2*a + b) 0

现在你可以试试

> ord2chr  [0,1,1,0,0,0,0,1]
'a'
于 2012-12-13T13:14:36.830 回答
4

正如我在评论中建议的那样,这个问题可以一分为二。这是第一部分的建议,我为了 Haskellness 声明了一个Bit类型:

data Bit = Zero | One

fromBits :: (Integral a) => [Bit] -> a
fromBits bits = foldl f 0 (zip [0..] (reverse bits))
    where
      f x (_, Zero) = x
      f x (n, One) = x + 2^n

那么这有什么作用呢?好吧,您的问题表明您的位列表首先具有最高有效位。我们将反向处理它,所以我们这样做reverse bits。然后,我们需要跟踪表示中两个不同元素的幂reverse bits,这就是ziping with[0..]所做的,产生 [(0, minimum-significant-bit), (1, second-least-significant bit), .. .]。最后foldl使用这个对列表,辅助函数f将 2 的适当幂添加到累加器。

我使用Integraltypeclass 不必选择整数类型。您可以在 8 位情况下使用Int,甚至。Word8对于更长的位列表,可以使用Integer任意精度(另请参见下面的 (*))。

对于第二部分,我们可以使用chr将 an 转换IntChar,如果我们知道我们的位列表不是太大(*),fromIntegral可以将我们的Integral类型转换aInt

所以,你想要的可以写成:

convert :: [Bit] -> Char
convert = chr . fromIntegral . fromBits

在你的情况下,convert [Zero, One, One, Zero, Zero, Zero, Zero, One]'a'

(*) 当然,如果它们是,那么转换无论如何都没有明显的意义。但这里有一点我想带回家:我们把问题分成两部分,结果证明第一部分(处理位列表)可以用一种更通用的方式来解决环境。例如,fromBits (One:(replicate 100 Zero))是 2^100。

于 2012-12-13T12:29:09.250 回答