第一章 位运算

第一章 位运算

一.运算符号:
&(与)、|(或)、^(异或)、~(非/取反);>>(二进制右移,用符号位填充高位)、<<(左移);>>>(用0填充高位);(无<<<);

二.题目:

思路:
法一 .^(异或):两个相同的数异或得0,根据这一特点:
(1)遍历1-1000,得到一个含有1-1000元素的数组x1。
(2)将创建的数组x1与原数组arr进行异或运算,得到的即为所求。

法二.暴力算法:
(1)创建一个数组helper。
(2)将原数组arr中的元素作为helper的下标进行遍历,每遍历一次:helper[arr[i]]++。
(3)遍历helper,如果为2,则输出helper的下标,即为所求。


import java.util.Random;
import java.util.Arrays;
public class 唯一成对的数1_1 {
   
	public static void main(String[] args)
	{
   
		int N=1001;
		int [] arr=new int[N];
		for(int i=0;i<N-1;i++){
   
			arr[i]=i+1;
		}
		//产生随机数
		arr[N-1]=new Random().nextInt(N-1)+1;//1~10之间的整数
		//随机下标
		int index=new Random().nextInt(N);//0~10
        swap(arr,index,arr.length-1);//arr[arr.length-1]与arr[index]交换
		System.out.println(Arrays.toString(arr));//输出
		//法一:
		int x1=0;
		for(int i=0;i<N-1;i++){
   
			x1=x1^(i+1);
		}
		for(int i=0;i<N;i++){
   
			x1=arr[i]^x1;
		}
		System.out.println(x1);
		
		
	    //法二
		int[] helper= new int[arr.length];
		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);
				break;
			}
		}   
	}
	//数组元素的交换
	private  static void swap(int[] arr,int i,int j){
   
         int temp = arr[i];
         arr[i] = arr[j];
         arr[j] = temp;
 }
}


思路:异或(依据:x^x=0)

import java.util.Scanner;
public class 找出落单的数1_2 {
   
	
	public static void main(String[] args)
	{
   
		Scanner sc=new Scanner(System.in);
		int N=sc.nextInt();
		int[] arr=new int[N];
		for(int i=0;i<N;i++){
   
			arr[i]=sc.nextInt();
		}
		find1(arr);
	}
	
	public static void find1(int[] arr){
   
		int x1=0;
		for (int i=0;i<arr.length;i++){
   
			x1=x1^arr[i];
		}
		System.out.println(x1);
	}
}

题3:二进制中1的个数
思路:
法一.左移<< : (num&(1<<i))==(1<<i)
法二.右移>>> : ((num>>>i)&1)==1
法三.-1,再&

import java.util.Scanner;

public class 二进制中1的个数1_3 {
   
	public static void main(String[] args){
   
		Scanner sc=new Scanner(System.in);
		int num=sc.nextInt();
		
		System.out.println(Integer.toString(num,2));
		
		//--------------法一:左移 1<<i
		int count=0;
		for(int i=0;i<32;i++)
		{
   
			if((num&(1<<i))==(1<<i))
			{
   
				count++;
			}
		}
		System.out.println(count);
		
		//--------------法二:右移
		count=0;
		for(int i=0;i<32;i++)
		{
   
			if(((num>>>i)&1)==1)
			{
   
				count++;
			}
		}
		System.out.println(count);
		
		//--------------法三:-1,再&
		count=0;
		while(num!=0)
		{
   
			num=((num-1)&num);
			count++;
		}
		System.out.println(count);
	}
}


思路:
只需判断其二进制数中1只出现在一个位上或者无1。

if(((N-1)&N)==0){
   
			System.out.println("yes");
		}


思路:
(1)分离出奇数位和偶数位对应的数字:与运算;
(2)再将奇偶数位对应的数字替换:位运算–偶数位右移,奇数位左移。

import java.util.Scanner;

public class 将整数的奇偶位互换1_5 {
   
	public static void main(String[] args){
   
		Scanner sc=new Scanner(System.in);
		int x1=sc.nextInt();
		int x2=exchange(x1);
		System.out.println(x2);
	}
	private static int exchange(int x){
   
		/* * 做与运算分别取出偶数位,奇数位 */
		int even=x&0xaaaaaaaa;//1010 1010 ……(16位)对应的16进制:0xaaaaaaaa
	    int odd =x&0x55555555;//0101 0101 ……
	  
	    return (even>>1)^(odd<<1);//达到互换的效果
	}
}

import java.util.Scanner;
public class 一以内的浮点数的二进制表示1_6 {
   
	public static void main(String[] args){
   
		Scanner sc=new Scanner(System.in);
		double n=sc.nextDouble();
		ToBin1(n);
		ToBin2(n);
	}
	
	//法一
	public static void ToBin1(double x){
   
		StringBuffer s=new StringBuffer("0.");
		int i=1;
		for ( ;i<=32;i++){
   
			x=x*2;
			s.append((int)x/1);
			x=x%1;
			if(x==0)
				break;
		}
		if(i>32){
   
			System.out.println("Error");
			return;
		}
		System.out.println(s);
	}
	
	//法二
	public static void ToBin2(double num){
   
		StringBuilder s=new StringBuilder("0.");
		while(num>0){
   
			//乘2:挪整
			double r=num*2;
			//判断整数部分
			if(r>=1){
   
				s.append("1");
				//消除整数部分
				num=r-1;
			}else {
   
				s.append("0");
				num=r;
			}
			if(s.length()>34){
    //前面“0.”占2个字符
				System.out.println("Error");
				return;
			}
		}
		System.out.println(s);
	}
	
}


思路:
k个相同的数对应的k进制相加,若不进位,相应位上为0;

public class 出现K次与出现11_7 {
   
	public static void main(String[] args){
   
		int[] arr={
   2,2,2,9,7,7,7,3,3,3,6,6,6,0,0,0,2,2,2,7,7,7,3,3,3,6,6,6,0,0,0};
		int len=arr.length;
		char[][] kRadix=new char[len][];//二维数组:存放k进制数
		int k=6; //k次
		
		int maxLen=0;//数转为k进制中的最长长度
		//转成k进制字符数组
		//对于每个数字
		for(int i=0;i<len;i++){
   
			//求每个数字的k进制字符串并翻转,然后转为字符数组
			kRadix[i]=new StringBuilder(Integer.toString(arr[i],k)).reverse().toString().toCharArray();
		    if(maxLen<kRadix[i].length)
		    	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 result=0;
		for(int i=0;i<maxLen;i++){
   
			//k进制每位余数乘对应的k次方--得到所求数字
			result+=(resArr[i]%k)*Math.pow(k,i);
		}
		System.out.println(result);
	}
}

三. 扩:
1.产生一个随机数:
new Random().nextInt(10) //产生0~9的整数
2.用户输入:
Scanner sc=new Scanner(System.in);
int n=sc.nextInt(); //用户输入整数
3.输出数组:
System.out.println(Arrays.toString(arr));
4.Java修饰符区别及使用情况:

类内部 本包 子类 外部类
public ✔ ✔
protected ✔ ✘
default ✘ ✘
private ✘ ✘

5.StringBuffer(如:):
StringBuffer s=new StringBuffer(“0.”);
s.append(“0”);
6.>>与>>>区别:

右移运算符 有无符号 移到右端的低位被舍弃,最高位? 举例 b=11010011
>> 有符号 移入原来低位的值 b>>2 = 11110100
>>> 无符号 补0 b>>>2 = 00110100

7.求数字n的k进制字符串并翻转,然后转为字符数组:
kRadix=new StringBuilder(Integer.toString(n,k)).reverse().toString().toCharArray();

全部评论

相关推荐

投递小天才等公司10个岗位
点赞 评论 收藏
分享
11-03 14:38
重庆大学 Java
AAA求offer教程:我手都抬起来了又揣裤兜了
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务