位运算-唯一成对的数

1.在处理中整型数值的时候,可以直接对组成整型数值的各个位进行操作,这就意味着可以使用屏蔽技术获得正数中的各个位(?,?)

可以使用屏蔽技术获得整数中的各个位

&(与)、|(或)、^(取反)、~(非)

>>、<<运算符将二进制进行右移或者左移操作

>>>运算符将用0填充高位; >>运算符用符号位填充高位,没有<<<运算符,对应int型,1<<35与1<<3是相同的而左边的操作数是long型的时候需要对右侧操作数模64

2.位运算的技巧:

①判断奇偶数

与1进行与运算,为1时为奇数,为0时为偶数

②获取二进制位是0还是1

③交换两个整数变量的值

例如a = 10100001,b = 00000110

 a = a ^ b   // a = 10100111

 b = b ^ a   // b = 10100001

 a = a ^ b   // b == 00000110

④不用判断语句求出整数的绝对值

2.问题描述:(下面是使用异或来消除重复的元素)

1-1000这1000个数字放在含有1001个元素的数组中,只有唯一的一个元素重复,其他均只出现一次,每个数组元素只能访问一次,设计一个算法,将它找出来;不用辅助空间,能否设计一个算法实现?

连续的数字异或可以消除重复

A^A = 0

(A^A)^B^(C^C) = B

但是我们的题目中是有两个元素重复,假如使用一次异或那么这个重复的元素就会被消除掉了,所以我们使用到一个小技巧来解决这个问题,使用两次异或的方法,那么重复的元素就会出现三次,那么就会消掉一个,其余不重复的元素均为两个,所以都被笑掉了,剩下的那个就是我们要求的那个重复的数字

代码如下:

import java.util.Random;
public class 唯一成对的数 {
    public static void main(String[] args) {
        int N = 11;
        int arr[] = new int[N];
        for(int i = 0;i<arr.length;i++){
            arr[i] = i + 1;
        }
        arr[arr.length-1] = new Random().nextInt(N-1)+1;
        int index = new Random().nextInt(N);
        Utils.swap(arr,index,arr[arr.length-1]);
        for(int i = 0;i<arr.length;i++){
            System.out.print(arr[i]+" ");
        }
        System.out.print("\n");
        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);
     }
}

Utils类为另外一个包的类,用来生成有一个重复元素的数组,代码如下:

public class Utils{
    public static void swap(int[] arr, int index, int j) {
          for(int i = 0;i<arr.length;i++){
              if(j==arr[i]){
                  arr[i] = arr[index];
                  break;
              }
          }
    }
}

除了上面的解法,我们通常的解法是借助辅助空间的办法来求解,

int helper[] = new int[11];
        for(int i = 0;i<helper.length;i++){
            helper[arr[i]]++;
        }
        
        for(int i = 0;i<helper.length;i++){
            if(helper[i]==2){
                System.out.print(i);
                break;
            }
        }

 还有一种方法是使用两重循环:

 for(int i = 0;i<arr.length;i++){
            for(int j = 0;j<i;j++){
                if(arr[i]==arr[j]){
                    System.out.print(arr[i]);
                    break;
                }
            }
 }

猜你喜欢

转载自blog.csdn.net/qq_39445165/article/details/81673989