位运算---算法的基础
Posted Heisenberg_Posion
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了位运算---算法的基础相关的知识,希望对你有一定的参考价值。
位运算,我们在学习中是很少碰到的,但是位运算还是有它自己独特的魅力
首先我们需要知道一些基本知识
对于int型1<<35和1<<3位是一样的,因为int只有32位,会进行取模操作
关于异或我们需要知道的
异或能交换两个数的值
与0异或的结果不变,与1异或结果相反
那么就有 a^0=a , a^a=0;
public void changeTwoNumber()
int a=2,b=1;
a=a^b;
b=a^b; //b=a^b^b =b=a^0=a
a=a^b; //a=a^b^a=b b已经变成a了
System.out.println(a+"+"+b);
题1:找出唯一成对的数
算法思想:
A,B,C,A是数组中的元素 , 先将数组中不重复的元素异或得到一个结果,再将这个结果与数组中的每个元素进行异或,留下来的那个数就是会重复的成对的数。
ABC^A (AB^C)
package com.zjl.bitOperation;
import org.junit.Test;
import java.util.Arrays;
import java.util.Random;
/**
* @author 朱佳林
* @version 1.0
* @englishName jack
*/
public class TheOnlyDoubleNumber
private final static int ArrayNum =11;
public static void main(String[] args)
//对数组进行赋值
int[] array=new int[ArrayNum];
for (int i = 0; i < ArrayNum-1; i++)
array[i]=i+1;
array[ArrayNum-1]=new Random().nextInt(ArrayNum-1)+1;
//将这个数与之前的某个数进行交换
int index=new Random().nextInt(ArrayNum-2);
int temp=array[ArrayNum-1];
array[ArrayNum-1]=array[index];
array[index]=temp;
int x=0;
System.out.println( Arrays.toString(array));
for (int i = 0; i <ArrayNum-1 ; i++)
x=x^(i+1);
for (int i = 0; i < ArrayNum; i++)
x=x^array[i];
System.out.println(x);
题2:找出落单的那个数
一个数组里除了某一个数字之外,其他的数字都出现了两次。请写程序找出这个只出现一次的数字。
算法思想,将数组里个每个数进行异或得到的最终结果就是落单的那个数,因为成对的数异或结果为0,落单的那个数与0异或结果就是自身。
package com.zjl.bitOperation;
import java.util.Arrays;
import java.util.Random;
/**
* @author 朱佳林
* @version 1.0
* @englishName jack
*/
public class TheOnlyNumber
public static void main(String[] args)
//初始化数据
final int ARRAY_NUM=1001;
int[] array=new int[ARRAY_NUM];
int value=0;
for (int i = 0; i <ARRAY_NUM-1 ; i++)
if (i%2==0)
value++;
array[i]=value;
array[ARRAY_NUM-1]=new Random().nextInt(10)+ARRAY_NUM/2+1;
//将这个数与之前的某个数进行交换
int index=new Random().nextInt(ARRAY_NUM -2);
int temp=array[ARRAY_NUM -1];
array[ARRAY_NUM -1]=array[index];
array[index]=temp;
System.out.println(Arrays.toString(array));
int result=0;
for(int arr:array)
result^=arr;
System.out.println(result);
题3:二进制中1的个数
package com.zjl.bitOperation;
import java.util.Scanner;
/**
* @author 朱佳林
* @version 1.0
* @englishName jack
*/
public class FindNum_1_number
public static void main(String[] args)
Scanner scanner = new Scanner(System.in);
System.out.println("Please input a number");
int testNum=scanner.nextInt();
int count=0;
for (int i = 0; i <32 ; i++)
//一位一位的去判断
if ((testNum&1<<i)==1<<i)
count++;
System.out.println(count);
题4:用一条语句判断一个整数是不是2的整数次方
算法思想:
2的整数次方-1之后的那个数的二进制位除了高位其余都为1与之前的数异或结果就为0
public void judgeNumTwo()
Scanner scanner = new Scanner(System.in);
int testNum=scanner.nextInt();
if (((testNum-1)&testNum)==0)
System.out.println("YES");
else
System.out.println("NO");
题5:0~1间浮点实数的二进制表示
如果无法表示,则输出ERROR
package com.zjl.bitOperation;
import org.junit.Test;
import org.omg.CORBA.PUBLIC_MEMBER;
import java.awt.*;
/**
* @author 朱佳林
* @version 1.0
* @englishName jack
*/
public class DecimalBinary
//野方法
public static void main(String[] args)
new DecimalBinary().judgeDecimal(0.875);
StringBuilder stringBuilder = new StringBuilder("0.");
double temp=0.625;
double last=temp;
for (int i = 1; i <33 ; i++)
double toReduce=Math.pow(2,-i);
//如果小,说明能减,那么就添上1,不能就补0
if (toReduce<=last)
last-=toReduce;
stringBuilder.append("1");
else
stringBuilder.append("0");
if (last==0)
System.out.println(stringBuilder.toString());
return;
if (stringBuilder.length()>34)
System.out.println("ERROR");
return;
//这是传统的方法,知道如何将小数转换为二进制数
//乘2,如果>1,则补1,然后减1,如果小于1,则继续乘2,直到这个数=0
public void judgeDecimal(double temp)
StringBuilder stringBuilder = new StringBuilder("0.");
while (temp>0)
temp=temp*2;
if (temp>=1)
stringBuilder.append(1);
temp-=1;
else
stringBuilder.append(0);
if (stringBuilder.length()>34)
System.out.println("ERROR");
return;
System.out.println(stringBuilder.toString());
题7:出现k次与出现1次
数组中只有-一个数出现了1次,其他的数都出现了k次,请输出只出现了1次的数。
2 个相同的2 进制数做不进位加法,结果为0
10个相同的10进制数做不进位加法,结果为0
k 个相同的k 进制数做不进位加法,结果为0
不进位加法也是异或运算,上述就是10个十进制的1相加如果不进位那肯定是0
这题会知道用java的一个类转进制就行,我觉得,因为有更好的方法map
Integer.toString(arr[i],k)
以上是关于位运算---算法的基础的主要内容,如果未能解决你的问题,请参考以下文章