位运算
最近刷了几道算法题,有一些是和位运算有关的,虽然位运算在源码中较多的出现,但个人仍认为其实操意义不大。不过不得不说,基于位运算的一些算法处理,有时候确实很神奇。因此做一个记录。
1. 异或:^, x ^ x=0, x ^ 0=x, x ^ 全1= ~x
2. 与 : & , x & x=x,x & 0=0,x & 1=x
3. 或:|,x | x=x,x |0=0,x | 1=x;
4. 取反:~
5. 左移:<<;移动一位:x<<=1;
6. 右移:>>
例题:
1~1000这1000个数放在含有1001个元素的数组中,只有唯一的一个元素值重复,其它均只出现一次。每个数组元素只能访问一次,设计一个算法,将它找出来;不用辅助存储空间,能否设计一个算法实现?
public static void main(String[] args) {
int N=1001;
int []arr=new int[N];
for(int i=1;i<N-1;i++){
arr[i]=i+1;
}
arr[N-1]=new Random().nextInt(N-1)+1;
int x1=0;
for(int i=1;i<=N-1;i++){
x1=x1^i;
}
for(int i=0;i<N;i++){
x1=x1^arr[i];
}
System.out.println(x1);
}
二进制中1的个数(一题三解)
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int N=sc.nextInt();
System.out.println(Integer.toString(N,2));
int count=0;
// //1.第一种方式
// for(int i=0;i<32;i++){
if((N&(1<<i))==(1<<i)){
count++;
}
// //第二种方式
// if(((N>>>i)&1)==1){
// count++;
// }
// }
while(N!=0){
N=(N&(N-1));
count++;
}
System.out.println(count);
}
交换一个数的二进制的奇偶位
public static void main(String[] args) {
int x=6;
System.out.println(Integer.toString(x,2));
System.out.println(Integer.toString(fun1(x),2));
}
public static int fun1(int x) {
int a = x & 0xaaaaaaaa;//1010 1010
int b = x & 0x55555555;//0101 0101
return (a>>1)^(b<<1);
}
数组中只有一个属出现了1次,其它的数都出现了k次,请输出只出现一次的数
public static void main(String[] args) {
int[]arr={2,2,2,9,7,7,7,3,3,3,6,6,6,0,0,0};
int len=arr.length;
char[][] radix=new char[len][];
int k=3;
int maxlen=0;
for(int i=0;i<len;i++){
radix[i]=new StringBuilder(Integer.toString(arr[i],k)).reverse().toString().toCharArray();
if(radix[i].length>maxlen){
maxlen=radix[i].length;
}
}
int[] resArr=new int[maxlen];
for(int i=0;i<len;i++){
for(int j=0;j<maxlen;j++){
if(j>=radix[i].length){
resArr[j]+=0;
}else{
resArr[j]+=(radix[i][j]-'0');
}
}
}
int res=0;
for(int i=0;i<maxlen;i++){
res+=(resArr[i]%k)*(int)(Math.pow(k,i));
}
System.out.println(res);
}