java打印对象内存地址 分布式事务 事务消息 分布式事务 几种解决方案 分布式事务-Seata 分布式事务-Seata 分布式事务-LCN-TCC 分布式事务-LCN 分布式事务-消息队列-定时任务-本地事件表 Zuul网关实战02 Zuul网关实战01 灰度发布落地实战2 灰度发布落地实战1 Gsnova on Heroku build Systemd Debian system initialization manage multi id_rsa ubuntu 64bits cannot run 32bits app REHL power auditing Debug Assembly for ARMv8 on QEMU ARM体系结构--寄存器 Run Debian iso on QEMU ARMv8 QEMU ARM64 guide cross compiler install buildroot install QEMU install python入门--数据结构 python入门--内置数据类型 python入门--类 异常 python入门--条件表达式 方法 python入门--数字 字符串 数组 RTC驱动分析 块设备驱动 TCP UDP socket 触摸屏驱动 USB驱动 LED按键中断 LCD 驱动 驱动信号 根文件系统 实验 内核实验 字符设备驱动程序 绪论 uboot 实验 LCD 实验 系统时钟和UART 中断控制器 Nand Flash控制器 MMU 实验 储存管理器实验 GPIO实验 点亮LED 编译加载驱动 制作烧写内核 dnw替代方法 MINI2440 TQ2440安装配套Linux 使用NFS 制作烧写跟文件系统 grub引导Windows 烧写裸版程序-linux Ubuntu 网络没有 eth0 Linux自动挂载 烧写裸板程序 电路基础 Mac词典 Vim插件 Assembly 综合研究 Assembly 指令总结 Assembly 直接定址表 Assembly 使用BIOS进行键盘输入和磁盘读写 Assembly 外中断 Assembly 端口 Assembly int指令 Assembly 内中断 Assembly 标志寄存器 Assembly 转移指令的原理 Assembly Call和ret指令 Assembly 数据处理两个基本问题 Assembly 灵活定位内存地址 Assembly 包含多个段的程序 Assembly [bx] loop Assembly 第一个程序 Assembly 寄存器 (内存访问) Assembly 寄存器 AWS VPN with EC2 hidden file in picture(linux) Assembly 基础 idea shortcuts 常用快捷键 idea plugin folder install ruby and jekyll

Bit

2020年10月31日

应用一:如何不用额外变量交换两个数:

异或运算,保证内存是2个独立的

交换操作:

a = a ^ b;

b = a ^ b;

a = a ^ b;

实际上倒的是2个空间

a = a ^ b; // 此时 a = a^b, b = b

b = a ^ b; // 此时 b = a^b^b = a, a=a^b

a = a ^ b; //此时 a = a^b^a = b, b = a

如果交换发生在同一个内存空间,就会出现问题:

swap(arrs, 0, 0) // 0和0位置交换,就会把 0 位置的值 计算成0

不要这么写,老老实实的写交换

应用二:一个数组中有一种数出现了奇数次,其他数都出现了偶数次,怎么找到并打印这种数

异或操作满足:交换律 和 结合律

异或 [ 2 1 3 2 2 4 1 3 1 2 4 1 4]

4个1

4个2

2个3

3个4

异或等同于 [ 1 1 1 1 2 2 2 2 3 3 4 4 4]

异或4个1 = 0

异或4个2 = 0

异或2个3 = 0

异或2个4 = 0,最后剩下4

应用三:怎么把一个int类型的数,提取出最右侧的1来

N & ( (~N) +1)

N = 0...0 1 1 0 1 0 1 0 0 0 0

~N = 1…1 0 0 1 0 1 0 1 1 1 1

~N+1= 1...1 0 0 1 0 1 1 0 0 0 0

再&N= 0…0 0 0 0 0 0 1 0 0 0 0

应用四:一个数组中有两种数出现了奇数次,其他数都出现了偶数次,怎么找到并打印两种数

先异或一遍所有数

int eor ^= arrs[i];

假设 a , b 是奇数次出现的数

得到的结果是 eor = a ^ b;

因为 a != b,所以 eor != 0,所以 eor 必有一个位置上是1

假设,第8位上是1

那么,a的第8位,和b的第8位不一样

所以,整个数组可以分为两大类:

第一类:第8位是1的数,也可能包含偶数的数

第二类:第8位是0的数,也可能包含偶数的数

但是,a和b一定不在同一类

随便在eor中找一位即可,所以找最右侧的1就可以

int rightOne = eor & ( (~eor) +1 ); //取到最右侧的1

再准备一个 eor ‘

重新遍历数组,异或,只异或第8位是1的数,第8位出现偶数的数 依然不会干扰,异或之后还是0,只有a或b被eor ‘抓到

所以 eor ‘ = a 或 b

因为 eor = a ^ b

所以另外一个数 = eor ^ eor ‘

a ^ b ^ b = a

a ^ b ^ a = b

应用五:随意给一个数,数出二进制1的个数

public static int bit1counts( int N ){

    int count = 0;

    while ( N != 0) {

    		// 011011010000	初始值

    		// 000000010000	最右侧1

    		// 011011000000	异或抹掉最右侧1,周而复始的

    	int rightOne = N & ( (~N) + 1);

    	count++;

    	N ^= rightOne;	//抹掉最右侧的1

    	// 注意 这里不能是 N -= rightOne 因为 N是正数可以,负数减的时候不是单纯的把1抹掉的形式

    }

}

如果不会这种技巧,只能用for循环32次