一、位运算
1、找出唯一成对的数
1-1000这1000个数放在含有1001个元素的数组中,只有唯一的一个元素值重复,其它均只出现一次。每个数组元素只能访问一次,设计一个算法,将它找出来;不用辅助存储空间,能否设计一个算法实现?
/**
* 题1:找出唯一成对的数
* 1-1000这1000个数放在含有1001个元素的数组中,只有唯一的一个元素值重复,其它均只出现一次。
* 每个数组元素只能访问一次,设计一个算法,将它找出来;不用辅助存储空间,能否设计一个算法实现?
*
* 本题思路:
* 利用异或的性质, x^i^i = x ,即将 1-1000 ^ arr[i] (0<=i<1001),两两异或抵消,只留有一个重复的
*/
import java.util.*;
public class 一 {
public static void main(String[] args) {
//首先创建数组
int N = 1001;
int[] arr = new int[N];
for (int i = 0; i<arr.length;i++){
arr[i] = i+1;
}
//最后一个数为随机数, Random().nextInt(-1) 生成的随机数为 [0-10),需要加1
arr[arr.length-1] = new Random().nextInt(N-1)+1;
int temp = 0; //0 ^ x = x
for (int i = 1;i<=N-1;i++){
temp = temp ^ i; //将 1 ~ N-1 都异或一次,即 1^2^3……^999^1000
}
for (int i = 0;i<N;i++){
temp = temp ^ arr[i]; //temp 原本的值为 1^2^3……^999^1000 ,然后再 ^ 1~1000 再加一个重复数,最后剩余重复数
}
System.out.println(temp);
}
}
还有暴力解法,不过需要开辅助存储空间,与题意不同,但简单
/**
* 题1:找出唯一成对的数
* 1-1000这1000个数放在含有1001个元素的数组中,只有唯一的一个元素值重复,其它均只出现一次。
* 每个数组元素只能访问一次,设计一个算法,将它找出来;不用辅助存储空间,能否设计一个算法实现?
*
* 本题思路:
* 利用异或的性质, x^i^i = x ,即将 1-1000 ^ arr[i] (0<=i<1001),两两异或抵消,只留有一个重复的
*/
/**
* 还有暴力解法,不过需要开辅助存储空间,与题意不同,但简单
*/
import java.util.*;
public class 一 {
public static void main(String[] args) {
//首先创建数组
int N = 1001;
int[] arr = new int[N];
for (int i = 0; i < arr.length; i++) {
arr[i] = i + 1;
}
//最后一个数为随机数, Random().nextInt(-1) 生成的随机数为 [0-10),需要加1
arr[arr.length - 1] = new Random().nextInt(N - 1) + 1;
// 辅助空间方法
int[] h = new int[N];
for (int i = 0; i < N; i++) {
//arr[i] 即 0-1000,有重复数, 原本h数组都是0,如果重复数是5,那 h[5]++ = 1;然后后来又发现了5,再 h[5]++ = 2,循环后找出结果为2的值的下标
h[arr[i]]++;
}
for (int i = 0; i < N; i++) {
if (h[i] == 2) {
System.out.println(i);
}
}
}
}
2、找出落单的那个数
一个数组里除了某一个数字之外,其他的数字都出现了两次。请写程序找出这个只出现一次的数字
此题比上题简单许多,还是利用异或,将所有数字异或,最后只剩下出现一次的数字
public class 二 {
public static void main(String[] args) {
//下面数组只有1 出现一次
int[] arr = {5, 6, 5, 6, 8, 8, 9, 9, 1, 2, 2};
int temp = 0;
for (int i = 0;i<arr.length;i++){
temp = temp ^arr[i];
}
System.out.println(temp);
}
}
3、二进制中1的个数
请实现一个函数,输入一个整数,输出该数二进制表示中1的个数。
例: 9的二进制表示为1001,有2位是1
方法一:利用转换二进制查询
import java.util.Scanner;
/**
* 二进制中1的个数
* 请实现一个函数,输入一个整数,输出该数二进制表示中1的个数。
* 例: 9的二进制表示为1001,有2位是1
*/
public class 三 {
public static void main(String[] args) {
int z = 0;
Scanner scanner = new Scanner(System.in);
int x = scanner.nextInt();
//整数二进制最高32位
int[] arr = new int[32];
while (x > 0) {
arr[z] = x % 2;
z++;
x = x / 2;
}
for (int i = 0; i < arr.length; i++) {
if (arr[i] == 1) {
x++;
}
}
System.out.println(x);
}
}
方法二:利用位运算符,将 1 左移然后利用 & 做对比(或者将原数右移,再和 1 &)
//方法二,利用位运算符
Scanner sc=new Scanner(System.in);
int N=sc.nextInt();
//输出二进制
System.out.println(Integer.toString(N,2));
int count = 0;
for (int i =0;i<32;i++){
if ((N&(1<<i)) == 1<<i){
count ++;
}
}
System.out.println(count);
}
方法三:利用二进制中的借位减一,并和原数&,消去最低位的1
//方法三
int count = 0;
Scanner sc=new Scanner(System.in);
int N=sc.nextInt();
while(N!=0){
N = (N-1)&N;
count ++;
}
System.out.println(count);
}
4、是不是2的整数次方
用一条语句判断一个整数是不是2的整数次方。
public static void main(String[] args) {
if (((8-1)&8) == 0){
System.out.println("8是");
}
}