【问题标题】:Two's Complement as simple as possible without higher order functions没有高阶函数的二进制补码尽可能简单
【发布时间】:2015-11-09 02:22:20
【问题描述】:

作为一项家庭作业,我被要求在 Haskell 中实现二进制补码方法,当给定二进制数字列表时,该方法会返回该列表的二进制补码列表。

>>>twoComplement [0,0,0,1,1,0,1,0]
[1,1,1,0,0,1,1,0]

因此我不允许使用高阶函数,例如lastinit等。这必须尽可能简单。我想学写漂亮的代码。

我想在不使用反向函数的情况下执行此操作,但如有必要,我可以这样做。

我已经尝试了很多东西。我知道我需要翻转所有位,这并不复杂。

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 功能尝试过的内容,其他人更有可能帮助您。你不能指望别人只为你写代码。
  • 另一种考虑二进制补码的方法是从右到左扫描您的位串直到碰到第一个,然后反转该位之后的所有位。
  • lastinit 不是 higher-order functions...
  • 我会将twoComplement 更改为在[Bool] 而不是(大概)[Int] 上进行操作,以便类型更紧凑。然后你就可以重写flipBits而不出现错误情况。
  • “我想学写漂亮的代码。”这通常意味着您使用更多而不是更少的库函数,尤其是包括预构建的递归方案。

标签: haskell twos-complement


【解决方案1】:

如果您不想反转,那么您随时可以看到一个原始数字和列表其余部分的结果。余数的结果是二进制补码加上一个进位数字。您必须返回相同类型的结果,即一个进位数字加上一个二进制补码,尽管还要考虑一个数字。

类似这样的:

invAdd :: Int -> (Int,[Int]) -> (Int,[Int])
invAdd 0 (0,ds) = (0,1:ds)
invAdd 0 (1,ds) = (1,0:ds)
invAdd 1 (0,ds) = (0,0:ds)
invAdd 1 (1,ds) = (0,1:ds)

现在如果你只有一个数字,那么整个操作将是:

twos :: [Int] -> (Int,[Int])
twos (d:[]) = invAdd d (1,[])

(1,[]) 迎合1,除了翻转位,您还必须添加。

如果你有多个数字,你需要向下递归

twos (d:ds) = invAdd d (twos ds)

这为您提供了二进制补码加上最后的进位位。不想看carry的话,用snd

*Main> snd (twos [0,0,0,1,1,0,1,0])
[1,1,1,0,0,1,1,0]

您也可以使用 Bools 轻松做到这一点,因为没有使用数学函数,并且在 invAdd 中明确说明了所有情况。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-17
    • 2012-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多