【发布时间】:2015-11-09 02:22:20
【问题描述】:
作为一项家庭作业,我被要求在 Haskell 中实现二进制补码方法,当给定二进制数字列表时,该方法会返回该列表的二进制补码列表。
>>>twoComplement [0,0,0,1,1,0,1,0]
[1,1,1,0,0,1,1,0]
因此我不允许使用高阶函数,例如last、init等。这必须尽可能简单。我想学写漂亮的代码。
我想在不使用反向函数的情况下执行此操作,但如有必要,我可以这样做。
我已经尝试了很多东西。我知道我需要翻转所有位,这并不复杂。
flipBits [] = []
flipBits (x:xs)
|x == 0 = 1:flipBits xs
|x == 1 = 0:flipBits xs
|otherwise: error "Only 0 and 1 are allowed."
但是添加一个部分对我来说真的很复杂。如果我将 1 添加到已经存在的 1 中,尤其是结转。也不允许使用列表生成器。这都是关于理解列表和连接器:。
编辑:在 vkuo 的帮助下,我编写了以下内容,到目前为止似乎做得很好。
twoComplement:: [Integer] -> [Integer]
twoComplement [] = []
twoComplement lst = turn(tC(turn(lst)))
where
tC (x:xs)
|x == 1 = 1:flipp xs
|x == 0 = x:tC xs
flipp [] = []
flipp(x:xs)
|x == 0 = 1:flipp xs
|x == 1 = 0:flipp xs
turn [] = []
turn (x:xs) = turn xs ++ [x]
如果我们想使用reverse,我们必须自己制作。所以我就这么做了。我想知道有没有反向的方法?
【问题讨论】:
-
显示您为
twoComplement功能尝试过的内容,其他人更有可能帮助您。你不能指望别人只为你写代码。 -
另一种考虑二进制补码的方法是从右到左扫描您的位串直到碰到第一个,然后反转该位之后的所有位。
-
last和init不是 higher-order functions... -
我会将
twoComplement更改为在[Bool]而不是(大概)[Int]上进行操作,以便类型更紧凑。然后你就可以重写flipBits而不出现错误情况。 -
“我想学写漂亮的代码。”这通常意味着您使用更多而不是更少的库函数,尤其是包括预构建的递归方案。