labuladong的算法小抄 ;本文只用于自我梳理,原链如上
[TOC]
一、字母转换大小写、大小写逆转(位运算)
转小写
char |=' '
; 转大写char &= '_'
;大小写逆转char ^=' '
;
给定字符串:zHaNSanKoiNIAHoinoiSAIODoijoIni
结果输出:
// 大小写需要 逆转 的
reverse:ZhAnsANkOIniahOINOIsaiodOIJOiNI
// 全大写
toUpperCase:ZHANSANKOINIAHOINOISAIODOIJOINI
// 全小写
toLowerCase:zhansankoiniahoinoisaiodoijoini
代码示例:
/**
* 转小写 char |=' ';
* 转大写 char &= '_';
* 大小写逆转 char ^=' ';
*/
@Test
public void testY() {
String s = "zHaNSanKoiNIAHoinoiSAIODoijoIni";
char[] result = new char[s.length()];
int i=0;
for(char tmp : s.toCharArray()) {
tmp ^= ' ';
result[i++] = tmp;
}
System.out.println("reverse:" + new String(result));
i = 0;
for(char tmp : s.toCharArray()) {
tmp &= '_';
result[i++] = tmp;
}
System.out.println("toUpperCase:" + new String(result));
i = 0;
for(char tmp : s.toCharArray()) {
tmp |= ' ';
result[i++] = tmp;
}
System.out.println("toLowerCase:" + new String(result));
}
二、判断两数字是否异号(位运算)
x^y<0 异或(同为0,异为1,判断两数字是否异号,只需判断两数符号位异或结果是否为负)
注意事项:0补码表示只有一种,0既不是正数也不是负数,没有+0,-0;若强加判断,补码中0符号位为0,隶属正数。
/**
* 0 的两种情况
*/
@Test
public void testJudgeTwoNums() {
int x = -0, y = 2, a = 0, b = -2;
System.out.println((x^y)<0); // false
System.out.println((a^b)<0); // true
}
三、不用临时变量交换两个数
int a = 1, b = 2;
a ^= b;
b ^= a;
a ^= b;
四、消除一个数二进制表示中最后一个1
n&(n-1)
-
计算汉明权重
@Test public void hammingWeight() { int n = 8; int res = 0; while (n != 0) { n = n & (n - 1); res++; } System.out.println("res二进制表示中1的个数:" + res); }
-
判断一个数字是不是2的指数(2的指数二进制表示中只包含一个1)
boolean isPowerOfTwo(int n) { if (n <= 0) return false; return (n & (n - 1)) == 0; }
五、查询只出现一次的元素
a ^ a = 0
;a ^ 0 = a
//给定非空正数数组,除了某个元素只出现一次外,其余元素均出现两次,找出只出现一次的那个元素
int singleNumber(int[] nums) {
int res = 0;
for (int n : nums) {
res ^= n;
}
return res;
}