位运算
1.<<,>>,及<<<
<< : 左移运算符,num << 1,相当于num乘以2
>> : 右移运算符,num >> 1,相当于num除以2
>>> : 无符号右移,忽略符号位,空位都以0补齐
public class Main {
public static void main(String[] args) {
//注意类型长度,int类型的长度为32位
//1左移35位,已经溢出了,按常理来说应该会为负数
//但是位数超过32位时,会取余再左移
//左移35位就变为100
System.out.println(1<<35);
//1移位32就不变了
System.out.println(1<<32);
//这个就变负数了,为什么?即1000...000,首位负数,那都是负数了
System.out.println(1<<31);
//1左移3,即1000 = 8
System.out.println(1<<3);
}
} 2.判断奇偶数
在二进制形式下,偶数最后一位必为0,奇数最后一位必为1
- x&1=0 -->偶数
- x&1=1 -->奇数
3.例题
1-1000这个1000个数放在含有1001个元素的数组中,只有唯一的一个元素只重复,其他均只出现一次。每个数组元素只能访问一次,设计一个算法,将他找出来;不用辅助存储空间,能否设计一个算法实现?
import java.util.Arrays;
import java.util.Random;
public class Main {
public static void main(String[] args) {
int N = 1001;
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);
swap(arr,index,arr.length-1);
System.out.println(Arrays.toString(arr));
/*
下面构造寻找方法
*/
//把数组所有的元素加起来,减去原来的,就剩下多出来的那个了
int total = 0;
for (int i = 0; i < arr.length ; i++) {
total += arr[i];
}
int usual = 0;
for (int i = 1; i <= N-1; i++) {
usual += i;
}
int outer = total - usual;
System.out.println(outer);
}
public static void swap(int[] arr, int index, int length) {
//暂存变量的值
int temp = arr[index];
arr[index] = arr[length];
arr[length] = temp;
}
} import java.util.Arrays;
import java.util.Random;
public class Main {
public static void main(String[] args) {
int N = 1001;
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);
swap(arr,index,arr.length-1);
System.out.println(Arrays.toString(arr));
/*
下面构造寻找方法
*/
//把数组所有的元素加起来,减去原来的,就剩下多出来的那个了
int x1=0;
for(int i=0; i<=N-1; i++){
x1 = (x1^i);
}
for(int i=0; i<N; i++){
x1 = x1^arr[i];
}
System.out.println(x1);
System.out.println("============");
int[] helper = new int[N];
for(int i=0; i<N; i++){
helper[arr[i]]++;
}
for(int i=0; i<N; i++){
if(helper[i]==2){
System.out.println(i);
}
}
}
public static void swap(int[] arr, int index, int length) {
//暂存变量的值
int temp = arr[index];
arr[index] = arr[length];
arr[length] = temp;
}
} 2、一个数组里除了某一个数字之外,其他的数字都出现了两次。请写程序找出这个只出现一次的数字。
public class Main {
public static void main(String[] args) {
int[] arr;
arr = new int[]{1,1,2,2,3,3,4,4,5,5,6};
int[] helper = new int[11];
for(int i=0; i<arr.length; i++){
helper[arr[i]]++;
}
for(int i=0; i<arr.length; i++){
if(helper[i]==1){
System.out.println(i);
}
}
}
} 3、请实现一个函数,输入一个整数,输出该数二进制表示中1的个数例:9的二进制表示为1001,有2位是1
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int X = scanner.nextInt();
System.out.println(Integer.toBinaryString(X));
int count=0;
for(int i=0; i<32; i++){
if((X&(1<<i))==(1<<i)){
count++;
}
}
System.out.println(count);
}
} 第二种解法:移动原数位将其与1对比
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int X = scanner.nextInt();
System.out.println(Integer.toBinaryString(X));
int count=0;
for(int i=0; i<32; i++){
if(((X>>>i)&1)==1){
count++;
}
}
System.out.println(count);
}
} 第三种解法:消除二进制上1的次数
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int X = scanner.nextInt();
System.out.println(Integer.toBinaryString(X));
int count=0;
while ( X!=0 ){
X=((X-1)&X);
count++;
}
System.out.println(count);
}
} 4、用一条语句判断一个整数是不是2的整数次方。
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int X = scanner.nextInt();
System.out.println(Integer.toBinaryString(X));
if(((X-1)&X)==0){
System.out.println("yes");
}else {
System.out.println("no");
}
}
} 4.将整数的奇偶位互换
public class Main {
public static void main(String[] args) {
int a = 9;
int b = m(9);
Assertions.assertThat(b).isEqualTo(6);
}
private static int m(int i){
int ou = i&0xaaaaaaaa;
int ji = i&0x55555555;
return (ou>>1)^(ji<<1);
}
} 5、给定一个介于0和1之间的实数,(如0.625),类型为 double,打印它的二进制表示(0.101,因为小数点后的二进制分别表示0.5,0.25.0.125.....)。
如果该数字无法精确地用32位以内的二进制表示,则打印“ERROR“
public class Main {
public static void main(String[] args) {
double num = 0.625;
StringBuilder sb = new StringBuilder("0.");
while(num>0){
//乘2:挪整
double r = num*2;
//判断整数部分
if(r>=1){
sb.append("1");
//消除整数部分
num = r - 1;
}else{
sb.append("0");
num = r;
}
if(sb.length()>34){
System.out.println("ERROR");
return;
}
}
System.out.println(sb.toString());
}
} 6、数组中只有一个数出现了1次,其他的数都出现了k次,请输出只出现了1次的数。
public class Main {
public static void main(String[] args) {
int[] arr = {2,2,2,9,7,7,7,3,3,3,6,6,6,0,0,0};
int len = arr.length;
char[][] kRadix = new char[len][];
int k = 3;
int maxLen = 0;
//转成k进制字符数组
//对于每个数字
for(int i = 0; i < len; i++){
//求每个数字的三进制字符串并翻转,然后转为字符数组
kRadix[i] = new StringBuffer(Integer.toString(arr[i], k)).reverse().toString().toCharArray();
if(kRadix[i].length > maxLen){
maxLen = kRadix[i].length;
}
}
int[] resArr = new int[maxLen];
for(int i=0; i<len; i++){
//不进位加法
for(int j=0; j<maxLen; j++){
if(j >= kRadix[i].length)
resArr[j] += 0;
else
resArr[j] += (kRadix[i][j] - '0');
}
}
int res = 0;
for(int i=0; i<maxLen; i++){
res += (resArr[i]%k)*(int)(Math.pow(k,i));
}
System.out.println(res);
}}

京公网安备 11010502036488号