面试:添加两个以字符串形式给出的二进制数

时间:2013-04-24 09:45:36

标签: c++ python string binary

http://www.glassdoor.com/Interview/Facebook-Interview-Questions-E40772.htm查看一些面试问题时,我遇到了以下问题:

  

给定二进制数字的两个字符串表示(例如“1001”,“10”),写一个添加它们的函数,并将结果作为字符串返回(例如“1011”)。

这是我开始为这个问题编写的一些Python代码(现在还不完整),但我不确定这是否是最好的(甚至是正确的)方法。我还考虑过首先在C ++中实现相同的功能,但放弃了考虑字符串操作中增加的复杂性。

def add_binary(a,b):
    temp = ""
    carry = false
    //i from len(a) to 1 and j from len(b) to 1
    bit_sum = add_bit ((a[i],b[j])
    if (bit_sum == "10"):
            temp.append("0")
            carry = true
    elif carry:
            temp.append(add_bit("1",bit_sum))
    else:
            temp.append(bit_sum)

    return temp.reverse()


def add_bit(b1, b2):
    if b1 == '0':
            return b2
    elif b2 == '0':
            return b1
    elif (b1 = '1' and b2 =='1'):
            return "10"
    else return None

a = "1001"
b = "10"
add_binary(a,b)

3 个答案:

答案 0 :(得分:2)

首先,如果字符串足够短(少于64位),我会 可能只是将它们转换为内部整数类型 (unsigned long long),在那里添加,然后 重新转换结果。在二进制字符串和。之间转换 内部格式确实非常简单。

否则,我可能会首先将它们规范化,以便它们具有 结果的最大长度。类似的东西:

size_t size = std::max( lhs.size(), rhs.size() ) + 1;
lhs.insert( lhs.begin(), size - lhs.size(), '0' );
rhs.insert( rhs.begin(), size - rhs.size(), '0' );

我还会创建一个这样大小的结果字符串:

std::string results( size, '0' );

进位变量,初始化为'0':

char carry = '0';

然后我使用反向迭代器遍历三个字符串, 或者更可能的是,只是一个索引(这将确保访问 每个字符串的相同元素):

size_t current = size;
while ( current != 0 ) {
    -- current;
    //  ...
}

在循环中,你真的只有四种可能性:我会 只计算'1'(lhs[current]rhs[current]和。{ carry),然后切换结果,设置 适当地results[current]carry

int onesCount = 0;
if ( carry == '1' ) {
    ++ onesCount;
}
if ( lhs[current] == '1' ) {
    ++ onesCount;
}
if ( rhs[current] == '1' ) {
    ++ onesCount;
}
swith ( onesCount ) {
case 0:
    carry = '0';
    results[current] = '0';
    break;

case 1:
    carry = '0';
    results[current] = '1';
    break;

case 2:
    carry = '1';
    results[current] = '0';
    break;

case 3:
    carry = '1';
    results[current] = '1';
    break;
}

就个人而言,我认为这是最简单,最干净的 解决方案,虽然有点冗长。或者,您可以替换 这个开关有:

results[current] = onesCount % 2 == 0 ? '0' : '1';
carry = onesCount < 2 ? '0' : '1';

最后,如果需要,您可以抑制中的任何前导零 结果(最多只有一个),也许可以断言 carry == '0'(因为如果不是,我们搞砸了我们的 计算大小)。

答案 1 :(得分:1)

这里最困难的部分是我们需要从右到左处理字符串。我们可以通过以下方式做到这一点:

  • 扭转字符串(输入和输出)。
  • 在递归调用中,在“返回”时处理这些位,即首先在“下一位”上调用递归加法,然后添加“当前位”。
  • 使用反向迭代器并从右到左构造结果。问题仍然是如何提前知道结果长度(所以你知道从哪里开始)。

当数字很大时,递归解决方案会出现问题,即堆栈可能会溢出。

扭转字符串是最简单的解决方案,但不是最有效的解决方案。

第一个和第三个选项的组合是使用反向迭代器反向处理输入字符串,但是以相反的顺序构造结果(所以你可以简单地追加位),然后反转结果。

这或多或少也是你的方法。实现从字符串长度减去1(!)到0的循环计数ij,因此这将以相反的顺序遍历输入字符串。如果carry设置为true,则在下一次迭代中向位总和添加一个。将add_bit的位和表示为整数,而不是再次表示为字符串,因此可以添加进位。

在C ++中,您可以使用rbegin()rend()以相反的顺序迭代任何序列。

答案 2 :(得分:0)

在Python中,您可以将字符串转换为int的整数,这也允许转换基础:

num = '111'
print int(num, 2)

打印7。

将结果转换回二进制文件:

print "{:b}".format(4)

打印100