作为Haskell的新手,我正在尝试添加两个n位二进制整数。
以下是我用C ++编写的内容,用于展示我想要实现的内容。任何人都可以告诉我如何在Haskell中做到这一点吗?
#include <iostream>
#include <vector>
#include <deque>
using namespace std;
int main()
{
vector<int> lhs{1,1,1,1}, rhs{1,0,1,1};
//! 3 inputs -> 2 outputs
deque<int> sum;
int carry = 0;
for( auto l = lhs.crbegin(), r = rhs.crbegin(); l != lhs.crend(); ++l, ++r)
{
int digit_sum = carry + *l + *r;
sum.push_front(digit_sum%2);
carry = digit_sum/2;
}
if(carry)
sum.push_front(carry);
for(auto b : sum)
cout << b << " ";
return 0;
}
输出:
1 1 0 1 0
下面是我在Haskell中停留的地方..
add :: (Int, Int, Int) -> (Int, Int)
add (l,r,c) = (((l+r+c) `mod` 2), ((l+r+c) `div` 2))
bAdd :: [Int] -> [Int] -> ([Int], Int)
bAdd [] [] = ([fst (add (0,0,0))], snd (add(0,0,0)))
bAdd [l] [r] = ([fst (add (l,r,0))], snd (add(l,r,0)))
bAdd (l:lt) (r:rt) = ([fst (add (l,r,add (head)))])
答案 0 :(得分:2)
我们先添加一位。
addWithCarry :: Bool -> Bool -> (Bool, Bool)
addWithCarry x y = (x /= y, x && y)
-- "x+y" its carry
然后,让我们转到列表:
-- numbers are represented LSB first e.g. 6 is [False,True,True]
addBitsWithCarry :: [Bool] -> [Bool] -> Bool -> [Bool]
-- when we ran out of digits on both args:
addBitsWithCarry [] [] False = []
addBitsWithCarry [] [] True = [True]
-- when we ran out of digits on one arg, add a zero there:
addBitsWithCarry a [] c = addBitsWithCarry a [False] c
addBitsWithCarry [] b c = addBitsWithCarry [False] b c
-- some digits on both sides
addBitsWithCarry (x:xs) (y:ys) c = ???
where (z,c') = addWithCarry ???
你能弄明白在最后几行做什么吗?
如果您可以假设您的数字具有相同的位长度(就像在C ++代码中那样),则可以删除上面添加零的两行。
额外提示:
-- some digits on both sides
addBitsWithCarry (x:xs) (y:ys) c = lsbOfTheSum : restOfTheSum
where (z,c') = addWithCarry someBit someOtherBit someCarry
lsbOfTheSum = ??? -- what is the first bit (LSB) of the result?
restOfTheSum = ??? -- how to compute the other bits (think recursively)
someBit = ??? -- what bit we should add at this step?
someOtherBit = ??? -- ... with what other bit?
someCarry = ??? -- ... using which carry?
如果您了解二元和的工作原理,并且您对Haskell,模式匹配和递归有基本的了解,那么您应该能够得出结论。