当我偶然发现一个问题以找出更改的位数或特定位数时,我正在经历编码挑战
计数要翻转以将A转换为B的位数
现在,对于W3C学校,我发现我们可以进行异或运算
const num1 = 10
const num2 = 20
const xorAandB = num1 ^ num2 //this would give 30
console.log(xorAandB)
const xorOfAandBToBits = xorAandB.toString(2)
console.log(xorOfAandBToBits) //11110 (5 numbers)
const num1ToBits = num1.toString(2)
console.log(num1ToBits) //(4 numbers)
我最初的想法是,一旦我两个都有位,就可以运行一个for循环来查看已更改的位
const num1ToBitsArray = num1ToBits.split('')
const xorBitsNumberToArray = xorOfAandBToBits.split('')
let count = 0
for (let i=0; i<num1ToBitsArray.length; i++) {
if (xorBitsNumberToArray[i] !== num1ToBitsArray[i]) count++
}
因此,基于此,我有两个问题
我如何使console.log(xorOfAandBToBits)
等于console.log(num1ToBits)
更好地完成任务
答案 0 :(得分:1)
您只需要检查数组中是否设置了某个位(您也可以只取字符串,而无需拆分):
if(xorBitsNumberToArray[i] === "1") count++;
如果xor返回,例如“ 1101”,这意味着3位不同,因此您实际上必须计算设置的位数。
否则我会这样做:
const difference = a ^ b;
let count = 0;
for(let i = 0; i < 32; i++)
count += (difference >> i) & 1;
答案 1 :(得分:1)
const num1 = 10
const num2 = 20
function dec2bin(dec){
return (dec >>> 0).toString(2);
}
const xor = dec2bin(num1 ^ num2);
count=0;
for(let x in xor){
if(xor[x]=='1'){
count++;
}
}
console.log(count)
答案 2 :(得分:1)
两个数字之间XOR
的二进制表示形式将具有等于1
的位,其中它们都具有不同的位。示例:
const num1 = 10;
const num2 = 20;
const xorAandB = num1 ^ num2;
console.log(num1, "->", "0" + num1.toString(2));
console.log(num2, "->", num2.toString(2));
console.log(xorAandB, "->", xorAandB.toString(2));
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}
因此,要计数要翻转以将 num1 转换为 num2 的位数,您需要计算{ {1}}代表1
。
对此的一种解决方案可以基于num1 XOR num2
(reference1,reference2)
从数字中减去
Brian Kernighan’s Algorithm
将切换所有位(从右到左)直到最右边的设置位(包括最右边的设置位)。因此,如果我们用1
减去一个数字并对其本身进行1
的按位与运算,则会取消设置最右边的设置位。如果我们在(n & (n-1))
中进行n & (n-1)
并计算loop
执行的次数,我们将获得设置的位数。此解决方案的优点在于,它循环的次数等于给定整数中的设置位数。
loop
Pseudocode:
1 Initialize count: = 0
2 If integer n is not zero
(a) Do bitwise & with (n-1) and assign the value back to n -> n := n & (n-1)
(b) Increment count by 1
(c) go to step 2
3 Else return count
const bitsToFlip = (num1, num2) =>
{
let num = num1 ^ num2, count = 0;
while (num)
{
num &= num - 1;
count++;
}
return count;
}
console.log("Bits to flip for (10, 20) =", bitsToFlip(10, 20));
console.log("Bits to flip for (1, 2) =", bitsToFlip(1, 2));
console.log("Bits to flip for (0, 7) =", bitsToFlip(0, 7));
甚至还可以将.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}
替换为下一个循环的while
循环,但不太可读:
for
答案 3 :(得分:1)
2:匹配XOR位字符串中的1的数目:
const bitsChanged = (xorBits.match(/1/g) || []).length;
/1/g
是regular expression,表示匹配字符串中的所有1,g是全局匹配标志,以返回所有匹配,而不仅仅是1。
|| []
确保如果数字相同则返回0。
const num1 = 10, num2 = 20;
const xorNum = num1 ^ num2;
const xorBits = xorNum.toString(2);
const bitsChanged = (xorBits.match(/1/g) || []).length;
console.log(bitsChanged + " bits differ");