数据结构与算法(Java)- 位运算基础入门

位运算

唯一的元素值

package com.lanqiao;

import java.util.Random;

public class UniquePairedNumbers {
    public static void main(String[] args) {
        /*1-1000这1000个数放在含有1001个元素的数组中,只有唯一的一个元素值重复,其它均只出现一次。
        每个数组元素只能访问一次,设计一个算法,将它找出来;不用辅助存储空间,能否设计一个算法实现?*/
        //定义那1001个元素,重复的那个使用随机数生成
        int N = 11;
        int[] a = new int[N];
        for (int i = 0; i < a.length - 1; i++)
            a[i] = i + 1;
        a[a.length - 1] = new Random().nextInt(N - 1) + 1;//随机数是从0到我指定的N随机生成
        for (int b : a) {
            System.out.print(b + " ");
        }
        System.out.println();
        //利用异或
        int x1 = 0, x2 = 0, ans = 0;
        for (int i = 1; i <= a.length - 1; i++) {
            x1 = x1 ^ i;
        }
        for (int i = 0; i < a.length; i++) {
            x2 = x2 ^ a[i];
        }
        //x1:1000个数^ x2:(1000个数^)^重复数 ans:(1000个数^)^(1000个数^)^重复数=重复数
        ans = x1 ^ x2;
        System.out.println(ans);
    }
}

二进制中1的个数

package com.lanqiao;

import java.util.Scanner;

public class NumberOfOneInBinary {
//    二进制中1的个数
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int N = scanner.nextInt();
        int ans = 0;
        System.out.println(Integer.toString(N, 2));
        //方法1:将1左移
        for (int i = 0; i < 32; i++) {
            //1<
            //例如 5 101 第一次 101 & 001 第二次 101 & 010 第三次 101 & 100
            if ((N & (1 << i)) == (1 << i)) {
                ans++;
            }
        }
        System.out.println(ans);
        //方法2:将1右移
        ans = 0;
        for (int i = 0; i < 32; i++) {
            //例如 5 101 第一次 101 & 001 第二次 010 & 001 第三次 001 & 001
            if (((N >> i) & 1) == 1) {
                ans++;
            }
        }
        System.out.println(ans);
        //方法3:记录消除1的次数
        ans = 0;
        while (N != 0) {
            //(n-1)&n能够消除最低位的1
            //例如 5 101 第一次 101&100=100 第二次 011&100=000
            N = (N - 1) & N;
            ans++;
        }
        System.out.println(ans);
        //判断一个数是否为2的整数次方可以转化为判断二进制中1的个数为1
    }
}

交换奇偶位

package com.lanqiao;

import java.util.Scanner;

public class OddEvenExchange {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int bin = scanner.nextInt();
        System.out.println(bin);
        System.out.println(Integer.toBinaryString(bin));
        bin = solution(bin);
        System.out.println(bin);
        System.out.println(Integer.toBinaryString(bin));
    }

    private static int solution(int bin) {
        int even = bin & 0xaaaaaaaa; //与1010 1010 ... (16进制8个a)做与运算取出偶数位
        int odd = bin & 0x55555555; //与0101 0101 ... (16进制8个5)做与运算取出奇数位
        //例如 9:1001 转换:even:1000->0100 odd:0001->0010 0100^0010=0110=6
        return (even >> 1) ^ (odd << 1);
    }
}

出现K次和出现1次

package com.lanqiao;

public class KOccurrencesAndOneOccurrence {
    public static void main(String[] args) {
//        数组中只有一个数出现了一次,其他的数都出现了k次,请输出只出现了1次的数。
        int[] arr = {3,3,3,2,2,2,7,7,7,9,0,0,0};
        int maxLen = 0;
        int n = arr.length;
        int k = 3;
        char[][] cache = new char[n][];
        // 预处理得到最大长度
        for (int i = 0; i < n; i++) {
            //将所有k进制数倒过来
            cache[i] = new StringBuilder(Integer.toString(arr[i],k)).reverse().toString().toCharArray();
            if (cache[i].length > maxLen) {
                maxLen = cache.length;
            }
        }
        int[] ans = new int[maxLen]; // 接收答案的数组
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < maxLen; j++) {
                // 第j位为空就补0
                if (j >= cache[i].length) {
                    ans[j] += 0;
                } else {
                    ans[j] += (cache[i][j] - '0');
                }
            }
        }
        int res = 0;
        for (int i = 0; i < ans.length; i++) {
            //取模得到第i位的值,再×k的i次方得到十进制答案
            res += (ans[i] % k) * (int) (Math.pow(k, i));
        }
        System.out.println(res);
    }
}

你可能感兴趣的:(java,开发语言,算法,笔记)