位运算在算法中常见的骚操作

常用用法

		//>>>表示高位补0 或者 >>有符号数补符号位
		System.out.println(1<<35);//8
		System.out.println(1<<3);//8

1.判断奇偶

		//奇数最低位为1,偶数最低位为0
		//直接与一&就能判断1为奇数,0为偶数
		int number;
		if(nember & 1 == 1){
		System.out.println("奇数");
		}else{
		System.out.println("偶数");
		}
2.获取二进制某一位到底是0还是1
		/**
		 * 判断一个二进制数的某一位是0还是1
		 * 
		 */
			int number = 7;
			int index = 1;
			//将一个数转换为二进制
			String binary = Integer.toBinaryString(number);
			//将number移到所要求的位置并相与
			int res = (number>>index)&1;
			System.out.println(res);

3.两个数的交换

			int number1 = 7;
			int number2 = 1;
			
			number1 = number1 ^ number2;
			number2 = number1 ^ number2;
			number1 = number1 ^ number2;
			System.out.println(number1 +""+number2);

4.不使用判断语句求一个数的绝对值

			
			int number1 = -7;
			
			System.out.println(number1 * (1 - ((number1 >>> 31)<<1)));

5.题目: 1-1000放在含有1001个元素的数组中, 只有唯一的一个元素值重复,其它均只出现一次. 每个数组元素只能访问一次,不能使用辅助空间

int[] n = new int[1001];
			
			//存放数字
			for(int i = 0 ; i < 1000; i++ ) {
				n[i] = i+1;
			}
			
			//生成所要的重复数字
			int random = new Random().nextInt(1000)+1;
			n[n.length-1] = random;
			System.out.println(random);
			
			//方法一采用求和做差的办法,但是不是最快的方法,而且也会出现溢出的情况
			int temp = 0;
			int temp1 = 0;
			
			for(int i = 1 ; i <= 1000 ; i++) {
				temp += i;
				temp1 += n[i-1]; 
			}
			temp1 += n[n.length-1]; 
			//重复数
			int res = temp1 - temp;
			System.out.println(res);
			
			/**
			 * 方法二异或
			 * 假设1^2^....^n...^n.....1000
			 * (1)1^2^..........^1000^n
			 * (2)设1^.....1000 = t
			 * (3)这个序列就为t^n
			 * (4)那么可以通过(t^t)^n = n求出重复数
			 */
			int result = 0;
			int result1 = 0;
			for(int i = 1 ; i<= 1000 ; i++) {
				result ^=i;
				result1 = result;
			}
			result1 ^= n[n.length-1]; 
			
			int res2 = result ^ result1;
			System.out.println(res2);

6.与上题相反,找出唯一一组只出现一次的数,其实是一致的方法

7.求一个二进制数中一的个数(或者0的个数)


		int number = 5;
		String binary = Integer.toBinaryString(number);
		int len = binary.length();
		/**
		 * 方法一或者说方法二
		 * 常规解法
		 * (1)对number移位/对一移位
		 * (3)用&
		 */
		
		//用于计数
		int count = 0;
		for(int i = 0 ; i < len ; i++) {
			//移動被操作數
			int temp = number >> i;
			if((temp & 1 )== 1)count++;
		}
		System.out.println(count);
/**
		 * 方法三:
		 * 计算的数与该数减一的 进行&运算,当计算结果为0时,程序结束
		 */
		 int num = 7;
		int count = 0;
		while (num)
		{
			num = num&(num - 1);
			count++;
		}

8.判断一个数是否是2的次幂,需要借鉴6,7题

我们发现2次幂的数二进制中只含有一个一

		int number = 4;
		int count = 0;
		while(number !=0) {
			number = number&(number-1);
			count++;
			
		}
		if(count == 1)
			{
				System.out.println("是2的次冪"); 
			}else {
				System.out.println("不是2的次冪");	
			}
		}

在一个数组中有一个数,其他数出现k次,找出这个只出现一次的数

//在一个数组中有一个数,其他数出现k次,找出这个只出现一次的数
        //存放数据的数组
        int[] nums = {2,2,2,3,4,4,4,5,5,5,1,1,1,9,9,9};
        //数据长度
        int len = nums.length;
        //出现次数
        int k = 3;
        /*
        存放每个进制转换后的长度,这是因为进制转换后每个数字位数可能不同
        列如:有三个数字进制转换
        2 2 1
        12
        2
        所以我们要设置maxlength来存放他们的位数
         */
        int maxLen = 0;//当然这里我们假设的是3
        //用一个二维数组存放进制转化后的结果
        char[][] ch = new char[len][];
        //将每一个数转换为k进制
        for(int i = 0 ;i < len ; i++ ){
        //每个数字进制转换并且字符串反转,转换为字符数组
        ch[i] = new StringBuilder(Integer.toString(nums[i],k)).reverse().toString().toCharArray();
        //找到最长的列数,为了我们求出每一位
               if(ch[i].length > maxLen) maxLen = ch[i].length;

        }

        /*
        完成后我们做不进位加法
         */
        int[] res = new int[maxLen];
        for(int i =0; i < len ; i++){
                for(int j = 0 ; j < maxLen ; j++){
                        if(j >= ch[i].length){
                                res[j]+=0;
                        }else{
                                //减0是为了将它转换成数字
                                res[j] += (ch[i][j]-'0');
                        }
                }
        }

        /*
        幂运算求出结果
         */
        int result =0;
        for(int i = 0 ; i <maxLen; i++){
                result += (res[i] % k)*(int)(Math.pow(k,i));
        }

        System.out.println(result);
发布了38 篇原创文章 · 获赞 1 · 访问量 2280

猜你喜欢

转载自blog.csdn.net/CRD8843/article/details/103465932