在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)
答案 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的循环计数i
和j
,因此这将以相反的顺序遍历输入字符串。如果carry
设置为true,则在下一次迭代中向位总和添加一个。将add_bit
的位和表示为整数,而不是再次表示为字符串,因此可以添加进位。
答案 2 :(得分:0)
int
的整数,这也允许转换基础:
num = '111'
print int(num, 2)
打印7。
将结果转换回二进制文件:
print "{:b}".format(4)
打印100