Haskell 从哈夫曼编码算法向文件写入字节
我正在学习Haskell,作为第一个挑战,我选择编写一个哈夫曼编码的实现,算法几乎完成了,只缺少将文件读写到字节文件的部分。 我需要做的是根据我构建的二进制字符串编写一个文件 例如,如果从Haskell 从哈夫曼编码算法向文件写入字节,haskell,byte,bit,Haskell,Byte,Bit,我正在学习Haskell,作为第一个挑战,我选择编写一个哈夫曼编码的实现,算法几乎完成了,只缺少将文件读写到字节文件的部分。 我需要做的是根据我构建的二进制字符串编写一个文件 例如,如果从txt文件中读取以下字符串Hello,在哈夫曼算法之后,我得到以下映射,该映射将符号映射为字符串形式的二进制数 [ ("H": "110"), ("e": "111"), ("l": "0"), ("o": "10") ] 我需要替换读取字符串中的字节,并将二进制数作为字节写入文件,我尝试使用
txt
文件中读取以下字符串Hello
,在哈夫曼算法之后,我得到以下映射,该映射将符号映射为字符串形式的二进制数
[
("H": "110"),
("e": "111"),
("l": "0"),
("o": "10")
]
我需要替换读取字符串中的字节,并将二进制数作为字节写入文件,我尝试使用ByteString包和writeFile函数,但该函数将二进制数作为纯文本而不是字节写入
这样一来,
Hello
传递为110111010
,应该以字节的形式写入文件 您可以将'0'
s和'1'
s字符串写入一个文件。例如:
main :: IO ()
main = writeFile "out.txt" "110111010"
您可以将Bool
s列表转换为Word8
s,但必须是8的倍数。例如,您可以使用0
s(或1
s,或其他东西)来“填充”,但它应该是8的倍数:
import Data.Bool(bool)
import Data.Bits((.|.), shiftL)
import Data.Word(Word8)
toWord8 :: [Bool] -> Word8
toWord8 = foldl ((. bool 0 1) . (.|.) . (`shiftL` 1)) 0
pack8pad0 :: [Bool] -> [Word8]
pack8pad0 [] = []
pack8pad0 xs
| null ys = [toWord8 (y ++ replicate (8 - length y) False)]
| otherwise = toWord8 y : pack8pad0 ys
where (y, ys) = splitAt 8 xs
我把把输入映射到
'0'
s和'1'
s的字符串作为练习。看看hPut
:只能以8的倍数传递位,可以用零填充位,或者使用字符(因此'1'
而不是位1
)。
import Data.Bool(bool)
import Data.Bits((.|.), shiftL)
import Data.Word(Word8)
toWord8 :: [Bool] -> Word8
toWord8 = foldl ((. bool 0 1) . (.|.) . (`shiftL` 1)) 0
pack8pad0 :: [Bool] -> [Word8]
pack8pad0 [] = []
pack8pad0 xs
| null ys = [toWord8 (y ++ replicate (8 - length y) False)]
| otherwise = toWord8 y : pack8pad0 ys
where (y, ys) = splitAt 8 xs