二进制相关算法

Posted 河畔的风

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二进制相关算法相关的知识,希望对你有一定的参考价值。

欢迎访问我的博客

总结

^: 两位相同为0,两位不同为1
&: 两位全为1则为1,否则为0
|: 两位中有一位有1则为1,否则为0
>>: 右移操作相当于除2
<<: 左移操作相当于乘2

十进制小数转换为二进制小数规定

    ## 整数部分: 除2取余,逆序排列
    ## 小数部分: 乘2取整,顺序排列
    例子: 173.8125
    173 => 101011101
    0.8125 => 0.1101
    0.8125 * 2 = 1.6250(取1) => 0.625 * 2 => 1.2500(取1) => 0.25 * 2 => 0.5(取0) => 0.5 * 2 = 1.0(取1)

负数的二进制表示方法

    负数以源码的补码表示
    负数的补码为对该数的原码除符号位外各位取反,然后在最后一位加1
    例:-10
           => 10000000 00000000 00000000 00001010 -10的源码
           => 11111111 11111111 11111111 11110101 -10的反码
           => 11111111 11111111 11111111 11110110 -10的反码加一

左移和右移运算 (>>, <<)

// 二进制的左移: m左移n位,最左边的n位被丢弃,右边补上n个0
// 二进制的右移:m右移n位,最右边的n位被丢弃,
// 如果数字是一个无符号数值,则用0填补最左边的n位,如果是负数,最左边补n个1
00001010 >> 2 => 00000010
10001010 >> 3 => 11110001

异或运算符(^)的操作

    使特定位翻转
    与0相异或, 保留原值

无符号右移运算符(>>>)

    运算符把 expression1 的各个位向右移 expression2 指定的位数。右移后左边空出的位用零来填充。移出右边的位被丢弃

js中操作符的妙用

    1. 使用&运算符判断一个数的奇偶
    例子: 2 & 1 // 0
    2. 使用~, >>, <<, >>>, |来取整
    例子: 6.83 >> 0 // 6
    3. 使用^来完成值交换
    例子: var a = 5
          var b = 8
          a ^= b
          b ^= a
          a ^= b
          console.log(a)   // 8
          console.log(b)   // 5
    4. 使用&, >>, | 来完成rgb值和16进制颜色值之间的转换
    \'\'\'
        #ffffff rgb(255, 255, 255)
        8位表示一个色度
        function hexToRGB(hex) {
            var hexx = hex.replace(\'#\', \'0x\')
            var r = hexx >> 16
            var g = hexx >> 8 & 0xff  // 去掉r 00 00 ff ff  & 00 00 00 ff
            var b = hexx & 0xff      // 去掉r, g // 00 ff ff ff ff & 00 00 00 ff
            return `rgb(${r}, ${g}, ${b})`
        }

        function RGBToHex(rgb) {
            var rgbArr = rgb.split(/[^\\d]+/)
            var color = rgbArr[1]<<16 | rgbArr[2]<<8 | rgbArr[3]
            return \'#\'+ color.toString(16)
        }
    \'\'\'
    5: (A|B|C|D) & D = D, 这个可以检测一个集合中是否有该值存在。

常见的算法题

汉明距离

题目来源

> 思路:
xor操作后,右移记录1的个数,右移为0就结束了循环
const hammingDistance = (x, y) => {
    let xor = x ^ y, count = 0
    while (xor) {
        if (xor & 1) count++
        xor >>= 1
    }
    return count
}

比特位计数

题目来源

> 思路:
奇数最后一位为1,偶数最后一位为0.
所以偶数的右移1位,1的个数不变。
奇数右移1位,1个个数减一。
因此得出:
如果 xx 是偶数,bit[x] = bit[x / 2]
如果 xx 是奇数,bit[x] = bit[x / 2] + 1
=>
bix[x] = bit[x >> 1] + (x & 1)
const countBits = num => {
    const result = new Array(num + 1).fill(0)
    for (let i = 0; i <= num; i++) {
        result[i] = result[i >> 1] + (i & 1)
    }
    return result
}

只出现一次的数字

题目来源

> 思路:
因为其他的元素都出现过两次,那么两个相同元素进行异或就是0
然后0 ^ 只出现一次的数字值不会变: 0000000 ^ 0110101 = 0110101
const singleNumber = nums => {
    return nums.reduce((acc, num) => acc ^= num, 0)
}

以上是关于二进制相关算法的主要内容,如果未能解决你的问题,请参考以下文章

片段(Java) | 机试题+算法思路+考点+代码解析 2023

二进制相关算法

遗传算法的基本原理

片段事务中的实例化错误

AJAX相关JS代码片段和部分浏览器模型

android.view.InflateException:二进制 XML 文件第 15 行:二进制 XML 文件第 19 行:膨胀类片段时出错