首页 > 解决方案 > 在 Haskell 中将 0-s 添加到直到长度为 8 的列表中

问题描述

所以我必须将一个十进制数变成二进制列表,如下所示:intToBitString 4 = [1,0,0]。我这样做了:

intToBitString n = reverse (helper n)

helper 0 = []
helper n 
        | n `mod` 2 == 1 = 1 : helper (n `div` 2) 
        | n `mod` 2 == 0 = 0 : helper(n `div` 2)

但是我还必须创建一个名为 intToByte 的函数,它用 0-s 填充列表,直到它的长度为 8 个元素。(所以使它成为一个字节串)像这样: intToByte 7 = [0, 0, 0, 0, 0, 1, 1, 1]

我尝试了很多东西,但它们从来没有奏效。我是初学者,所以我只知道上面显示的“if”循环和递归,但我不知道任何花哨的东西。我的尝试之一:

intToByte 0 = [0]

intToByte n
        | eight n == helper2 n = reverse (helper2 n)
        | otherwise = eight n

helper2 0 = []
helper2 n 
        | n `mod` 2 == 1 = 1 : helper2 (n `div` 2) 
        | n `mod` 2 == 0 = 0 : helper2 (n `div` 2)

eight n
        | length (helper2 n) < 8 = 0 : eight n
        | otherwise = helper2 n

我已经为此工作了很多小时,以至于我对此感到困惑。但这是一项重要任务的一部分,因此非常感谢您的帮助!

标签: listhaskellrecursionfunctional-programmingbinary

解决方案


首先,您可以通过以下方式简化代码:

helper2 :: Integral i => i -> [i]
helper2 0 = []
helper2 n = r : helper2 q
    where (q,r) = quotRem n 2

其次,上面是一个大端表示[wiki]。实际上,7表示为[1,1,1],而14例如表示为[0,1,1,1]。如果我们想扭转这种情况,我们可以使用累加器:

helper2 :: Integral i => i -> [i]
helper2 = go []
    where go rs 0 = rs
          go rs n = go (r:rs) q
              where (q,r) = quotRem n 2

因此,这映射7[1,1,1]和。但是现在我们仍然需要添加前导零。例如,我们可以通过维护已添加到列表中的元素数量来做到这一点:14[1,1,1,0]

eight :: Integral i => i -> [i]
eight = go [] 0
    where go rs l 0 = replicate (8-l) 0 ++ rs
          go rs l n = go (r:rs) (l+1) q
              where (q,r) = quotRem n 2

推荐阅读