题目描述:
给你两个二进制字符串,返回它们的和(用二进制表示)。
输入为 非空 字符串且只包含数字 1 和 0。
今日学习:
1.BigInt()
2.位运算&、^、<<1
3.js进制之间的转换
题解:1.位运算(不用四则运算符)2.反转运算3.转10进制
//纯位运算,但是js会溢出
const addBinary = (a, b) => {
a = parseInt(a, 2);
b = parseInt(b, 2);
while (b != 0) {
let carry = a & b;
a = a ^ b;
b = carry << 1;
}
return a.toString(2);
};
//纯位运算
const addBinary = (a, b) => {
while (a.length > b.length) b = '0' + b
while (a.length < b.length) a = '0' + a
let res = new Array(a.length)
let val // 当前位不进位的相加结果
let carry // 当前位的进位
let carryFromBefore // 当前相加是否有来自上一位的进1
for (let i = a.length - 1; i >= 0; i--) {
val = Number(a[i]) ^ Number(b[i]) // 异或是不带进位的相加
carry = Number(a[i]) & Number(b[i]) // 求出当前位的进位
if (carryFromBefore) { // 有来自上一位的进位
if (val == 0) {
val = 1 // 加上进位 变为1
} else { // 当前位1 + 进位1 = 2
carry = 1 // 往前进1
val = 0 // 当前位为0
}
}
carryFromBefore = carry // 给下一轮迭代使用的进位
res.unshift(val) // 从res数组的前头推入
}
if (carry) res.unshift(1) // 循环结束,还有进位,就要多加1
return res.join('')
}
//我自己的想法
var addBinary = function(a, b) {
let res = []
//存进位标志
let flag = 0
//方便运算
if(a.length > b.length) {
[a, b] = [b, a]
}
a = a.split("").reverse()
b = b.split("").reverse()
//先直接相加再处理
for(let i = 0; i < b.length; i++) {
if(i < a.length) {
res[i] = Number(a[i]) + Number(b[i])
// res[i] = a[i] + b[i]
}
else {
res[i] = Number(b[i])
// res[i] = b[i]
}
}
for(let i = 0; i < res.length; i++) {
if(res[i] == 0) {
// if(res[i] == '0' || res[i] == '00') {
if(flag == 0) {
res[i] = 0
}else {
res[i] = 1
flag = 0
}
}
else if(res[i] == 1) {
// else if(res[i] == '1' || res[i] == '01' || res[i] == '10') {
if(flag == 0) {
res[i] = 1
}else {
res[i] = 0
flag = 1
}
}
else if(res[i] == 2) {
// else if(res[i] == '11') {
if(flag == 0) {
res[i] = 0
flag = 1
}else {
res[i] = 1
flag = 1
}
}
}
if(flag == 1) res.push(1)
return res.reverse().join("")
};
//js这样算会溢出
var addBinary = function(a, b) {
a = parseInt(a, 2)
b = parseInt(b, 2)
let res = a + b
return parseInt(res).toString(2)
}
//但是BigInt可以解决溢出问题
var addBinary = function(a, b) {
return (BigInt('0b' + a) + BigInt('0b' + b)).toString(2)
}