案例训练1.23:进制运算、位数运算

文章讲述了对进制的新理解,包括十进制、十二进制和十六进制的转换,并通过示例展示了如何利用进制和位运算解决sky数判断问题、求集合子集以及检测只出现一次的数。
摘要由CSDN通过智能技术生成

一.进制

今天对进制有了新的理解,拿最常见的十进制,我们求每一个位时都用n%10,n/10反复循环直到n==0,对于其他进制也一样,都拿对应的数进行这样的操作(数是一定的,进制不同呈现的样子也不同)。

案例一:判断是不是sky数

skys数,如果n的十进制、十二进制、十六进制的四位数相加的和都相同

import java.util.ArrayList;
import java.util.Scanner;

public class 进制练习sky数 {
    public static void main(String[] args) {
        //skys数,如果n的十进制、十二进制、十六进制的四位数相加的和都相同
        //判断是不是sky数

        Scanner sc=new Scanner(System.in);
        //方法一(且对多个数判断,以0来停止数输入)
        ArrayList<Integer> list=new ArrayList<>();
        while (true){
            int n=sc.nextInt();
            if(n==0){
               break;
            }
            if(n<10000){
                list.add(n);
            }
        }
        for(int j=0;j<list.size();j++){
        int[]arr={10,12,16};
        int[]arr1=new int[3];
        for(int i=0;i<arr.length;i++){
            int temp=list.get(j);
            int count=0;
            while (temp!=0){
                count=count+temp%arr[i];
                temp=temp/arr[i];
            arr1[i]=count;
            }
        }
            if (arr1[0]==arr1[1]&&arr1[1]==arr1[2]){
                System.out.println(list.get(j)+" is a Sky Number.");
            }else {
                System.out.println(list.get(j)+" is not a Sky Number.");
            }
        }


    }
  
}

这道题,一般思路是将数分别转化为对应的进制的字符串,再将每个字符提取出来根据Ascall码来计算,然后再相互比较,但是这样的编码长且重复且复杂。

但是通过对进制的理解,可以用一个循环用相应的进制数对n%x,n/x进行反复循环并将其余数相加就是所有位数和。

案例二:集合求子集

public class Main {
    public static void main(String[] args) {
        //给定一个集合求它的所有子集
        int[]arr={1,2,3,4};
        //放到相应的二进制里
        for(int i=0;i<=Math.pow(2,4)-1;i++){
            String s=Integer.toString(i,2);
            String len="{";
            for (int j=0;j<s.length();j++){
                if(s.charAt(j)=='1'){
                    len=len+arr[j]+" ";
                }
            }
            len=len+"}";
            System.out.println(len);
        }
    }
}

这道题最最最最最最关键的思路就在于把这个集合放入二进制中,如集合[1,2,3,4]对应的二进制为0000到1111,再创建数组通过循环嵌套可以将所有子集情况都输出

最关键的核心思想就是和二进制结合,也考验了对进制的理解

二.位运算

&且、|或、^异或都是用两个数的二进制进行计算 最后重新排列组成二进制,再将二进制转化为10进制输出

&:如果同位都为1则1,不然则0

System.out.println(7%3);//3

|:有1就1,没1就0

System.out.println(7|3);//7

^:如果相同则0,不同则1,可以用于两数交换

System.out.println(7^0);//7

案例一:给定一个数n,判断是否非2的n次;(对&的掌握)

import java.util.Scanner;

public class 位运算实践1 {
    public static void main(String[] args) {
        //给定一个数n,判断是否非2的n次;
        Scanner sc = new Scanner(System.in);
        //正常方法有很多,比如一直除以2,下面是两种简单快捷的方式
        //两种新的思维,对进制和位运算的掌握
        //1.位运算(重点)
        int a = sc.nextInt();
        System.out.println((a & (a - 1)) == '0' ? "YES" : "NO");
        }
}

&将数变成二进制展开,相应位置都为一则一,不然则0。根据这个性质可以推出a=a & (a - 1))作用是把最右边的那个1变为零,根据这个特性我们把其放在循环里配合count就能求出1的个数,如果大于1则说明n不是2的次方。

案例二:求n的二进制有多少个1

import java.util.Scanner;

public class 位运算实践2 {
    public static void main(String[] args) {
        //求整数n的二进制中有多少个1
        //常用方法:1.n->2进制,用for循环统计里面的1的个数
        //         2.把循环n%2,n/2 求有多少个1余下

        //位运算
        //&相应为都为1才是1
        //a&(a-1)的作用是把a二进制最右边的1变成0(自己再思考一下,不能死记)
        Scanner sc=new Scanner(System.in);
        int a=sc.nextInt();
        int count=0;
        while (a!=0){
            a=a&(a-1);//做一次,就是把a的最右边的1变成0
            count++;//计数
        }
        System.out.println(count);






    }
}

与第一题同理,&将数变成二进制展开,相应位置都为一则一,不然则0根据这个性质可以推出a=a & (a - 1))作用是把最右边的那个1变为零,根据这个特性我们把其放在循环里配合count就能求出1的个数。

案例三:异或位运算,求一组数中只出现了一遍的数

异或^t特性: 

a^b^j^k^l^i与a^l^j^b^k^i相同

i^i=0 i^0=i

import java.util.Scanner;

public class 位运算3异或位运算 {
    public static void main(String[] args) {
        //异或^
        //a^b^j^k^l^i与a^l^j^b^k^i相同
        //i^i=0 i^0=i

        //求只出现一次的数
        Scanner sc=new Scanner(System.in);
        int n=sc.nextInt();
        int asc=0;
        for(int i=0;i<2*n-1;i++){
            asc=asc^sc.nextInt();
        }
        System.out.println(asc);


    }
}

掌握了这些特性,可以知道如果重复了的数通过异或符号为零,而只出现了一遍的数^0则等于本身,那么我们只需要将所有数共同异或,并最后异或0就能得到只出现了一次的数

pass:小技巧

由于int和String都可以通过Integer进行转化,但是由于比较大的进制每一位可能是英文,所以转化时int只接收10进制、String接收其他进制,所以如果要准化成其他进制用Integer.toString转化为对应进制字符串,反之转化成10进制则用Integer.parseInt();转化成10进制int.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值