菜鸟日记—1月18日
案例1:
数组中确定唯一成对的数
1~N-1在长度为N的数组中,只有唯一一个元素值重复,其它均只出现一次
每个数组元素只能访问一次,设计一个算法将他找出来,不用辅助空间
*第一种方法
构造新数组与其进行与运算
先构造数组
public class 数组中确定唯一成对的数 {
public static void main(String[] args) {
int N = 11; //N可自己自行设置
int[] arr = new int[N];
for (int i = 0; i < arr.length-1; i++) {
arr[i] = i + 1;}
最后一个数取随机数,并与前面随机一个元素对换位置
//最后一个数取随机数
arr[arr.length-1] = new Random().nextInt(N-1)+1;
//随机下标
int index = new Random().nextInt(N);
//最后一个数与前面随机一个数互换位置
int t=arr[N-1];
arr[N-1]=arr[index];
arr[index]=t;
System.out.println(Arrays.toString(arr));
int x = 0;
构造新数组与其进行与运算并输出
//构造一个1~N-1的数组
for (int i = 0; i < N-1; i++) {
x = x ^ (i + 1);
}
//新数组与旧数组作亦或运算,其余相同的数亦或为零
//而成对的数加新数组里面那个数则有3个,所以亦或结果便是成对的那个数
for (int i = 0; i < N; i++) {
x ^= arr[i];
}
System.out.println(x);
*第二种方法
辅助空间解法(暴力破解)
int[] f = new int[N];
for (int i = 0; i <N ; i++) {
f[arr[i]] += 1;//原先每个元素都是0,现在给下标为arr[i]的每个都加1
//因为其中有两个数是一样的,所以会加两次
}
//System.out.println(Arrays.toString(f));
for (int i = 0; i < N; i++) {
//当新数组中某个元素等于2时,那么他的下标就是重复的那个数
// (因为第一个元素被0占用了,所以下标不用加一)
if(f[i]==2){
System.out.println(i);
}
}
}
}
效果图:
每次结果都不一样
案例2:
求二进制中’1’的个数
输一个整数,判断其二进制中有多少个’1’
有三种解法
1.从右往左依次比对
public class 二进制中1的个数 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int N = sc.nextInt();
System.out.println(Integer.toString(N,2));
//1.从右往左挨个比对是否为1
int count1 = 0;
for (int i = 0; i < 32; i++) {
if ((N&(1<<i))==(1<<i)){
count1++;
}
}
System.out.println(count1);
2.从左往右依次比对
int count2 = 0;
for (int i = 0; i < 32; i++) {
if (((N>>i)&1)==1){
count2++;
}
}
System.out.println(count2);
3.减1法
通过将输入的数减1与原数进行与运算,与几次就有几个1
int count3 = 0;
//因为不知道要循环几次,所以用while
while (N != 0){
N = (N-1)&N;
count3++;
}
System.out.println(count3);
}
}
下面是减1法的图解,些许潦草,别介意
假设输入的数是20,有两个1,则与两次
效果图:
案例3:
是不是2的整次方
输入一个数,判断其是不是2的整数次方
思考:当一个数的二进制位上有且只有一个1时,那么他便是2的整数次方;
比如:8只有从右往左第4位为一,64则是第7位
public class 是不是2的整次方 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int N = sc.nextInt();
int a = 2;
if ((N & (N - 1)) == 0){
System.out.println("yes");
}
else {
System.out.println("no");
}
}
}
效果图:
案例4:
奇偶位互换
给出一个整数,将他的二进制奇偶位互换,并验证互换是否成功
如9的二进制为: 1001,奇偶位互换后为:0110等于6
public class 交换奇偶位 {
public static void main(String[] args) {
int a = 9;
int b = huan(a);
//验证换位是否成功,9奇偶位互换等于6
int c = 6;
System.out.println(b);
if (c == b){
System.out.println("yes");
}
}
private static int huan(int i) {
//这里用二进制太长了,我用十六进制表示
int ji = i & 0x55555555; //和1010 1010 1010 1010......做与运算取出奇数位
int ou = i & 0xaaaaaaaa; //和0101 0101 0101 0101......做与运算取出偶数位
return (ji << 1) ^ (ou >> 1); //合并成一个二进制数
}
}
图解:
假设要互换的数是9
效果图:
over!!!
寒冷而充实的一天结束。