美文网首页
基础练习 十六进制转八进制

基础练习 十六进制转八进制

作者: 就这样吧嘞 | 来源:发表于2018-12-20 19:41 被阅读0次

    问题描述
      给定n个十六进制正整数,输出它们对应的八进制数。

    输入格式
      输入的第一行为一个正整数n (1<=n<=10)。
      接下来n行,每行一个由0-9、大写字母A-F组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000。

    输出格式
      输出n行,每行为输入对应的八进制正整数。

    【注意】
      输入的十六进制数不会有前导0,比如012A。
      输出的八进制数也不能有前导0。

    样例输入
      2
      39
      123ABC

    样例输出
      71
      4435274

    【提示】
      先将十六进制数转换成某进制数,再由某进制数转换成八进制。

    进制转换方法:https://jingyan.baidu.com/article/47a29f24292608c0142399cb.html
    解题思路:十六进制转二进制,再转八进制
    需要解决的问题:
    1.输入
    2.字符分解
    3.进制转换
    4.可能需要补开头0
    5.转换存储输出

    第一次提交

    import java.util.Scanner;
    
    public class Main {
    
        public static void main(String[] args) {
            Scanner sc=new Scanner(System.in);
            int n=sc.nextInt();
            String [] strarr=new String [n];
            for(int i=0;i<n;i++) {
                strarr[i]=sc.next();
            }
            for(int i=0;i<n;i++) {
                sixteenzhuaneight(strarr[i]);
            }       
        }
        
        public static void sixteenzhuaneight(String str) {
            String chuan= "";
            for(int i=0;i<str.length();i++) {   //遍历各个字符
                char danzifu=str.charAt(i);    
                chuan=chuan+tenzhuantwo(danzifu);//连接二进制字符
            }
            //此时chuan已经为输入值二进制
            String number="";
            for(int i=0;i<(chuan.length()/3)+1;i++) {
                String guo;
                if(chuan.length()-3*i-3<0) {
                    guo=chuan.substring(0,chuan.length()-3*i);
                }
                else {
                    guo=chuan.substring(chuan.length()-3*i-3,chuan.length()-3*i);
                }
                number=twozhuaneight(guo)+number;
            }
            //对number去0
            String shuchunumber="";
            for(int i=0;i<number.length();i++) {
                if(number.charAt(i)=='0') {     
                }
                else {
                    shuchunumber=number.substring(i, number.length());
                    break;
                }
            }
            System.out.println(shuchunumber);   
        }
        
        public static String tenzhuantwo(char x) {
            int number;
            switch(x){
            case 'A':
                number=10;
                break;
            case 'B':
                number=11;
                break;
            case 'C':
                number=12;
                break;
            case 'D':
                number=13;
                break;
            case 'E':
                number=14;
                break;
            case 'F':
                number=15;
                break;
            default:
                number=x-'0';                             //强制转换未考虑其他字符
            }
            String begin=Integer.toBinaryString(number);  //转二进制        
            while(begin.length()<4) {                     //补0
                begin="0"+begin;
            }
            return begin;   
        }
        public static char twozhuaneight(String x) {//三合一二级制转八进制
            int number = 0;
            for(int i=0;i<x.length();i++) {
                char shu=x.charAt(x.length()-1-i);
                switch(shu) {
                case '1':
                    number=(int) (number+Math.pow(2, i));
                    break;
                case'0':
                    number=number;
                    break;
                default:
                    break;
                }
            }
            char cNumber= (char) (number+'0');
            return cNumber;
        }
    
    
    }
    
    

    结果超时
    分析原因,用了较多的for,造成超时
    网上找到这个方法直接转
    Integer.toOctalString(Integer.valueOf(要转的字符串,16))
    再次尝试

    import java.util.Scanner;
    
    public class Main {
    
        public static void main(String[] args) {
            Scanner sc=new Scanner(System.in);
            int n=sc.nextInt();
            String [] strarr=new String [n];//存储输入
            for(int i=0;i<n;i++) {
                strarr[i]=sc.next();
            }
            for(int i=0;i<n;i++) {
                String number=Integer.toOctalString(Integer.valueOf(strarr[i],16));
                System.out.println(number);
            }
        }
    
        }
        
    
    

    运行错误
    。。。。。。???
    测试发现只能最多转换8位字符串
    。。。。。。。。。。

    回归原点,优化原来的代码,原先是先转二进制再转八进制,如果直接转化位八进制应该能减少复杂度。不难发现3位十六进制可以转换为4位八进制,我们可以利用
    Integer.toOctalString(Integer.valueOf(要转的字符串,16))直接转换,从而避免字符位数不够
    需要解决的问题,转化后需要补零以及消除零

    新的代码

    import java.util.Scanner;
    
    public class Main {
    
        public static void main(String[] args) {
            Scanner sc=new Scanner(System.in);
            int n=sc.nextInt();
            String [] strarr=new String [n];//存储输入
            for(int i=0;i<n;i++) {
                strarr[i]=sc.next();
            }
            
            for(int i=0;i<n;i++) {
                String shuchu=zhuanhuan(strarr[i]);
                System.out.println(shuchu);
            }
        }
        public static String zhuanhuan(String x) {//十六转八
            String arrx="";
             for(int i=0;i<(x.length());i+=3) {
                    String guo;
                    if(x.length()-i-3<0) {
                        guo=x.substring(0,x.length()-i);
                    }
                    else {
                        guo=x.substring(x.length()-i-3,x.length()-i);
                    }
                    String sifu=Integer.toOctalString(Integer.valueOf(guo,16));
                    switch(sifu.length()) {//补零
                    case 4:
                        break;
                    case 3:
                        sifu="0"+sifu;
                        break;
                    case 2:
                        sifu="00"+sifu;
                        break;
                    case 1:
                        sifu="000"+sifu;
                        break;
                    default:
                        break;
                    }
                    arrx=sifu+arrx;//连接字符
                }
             for(int i=0;i<arrx.length();i++) {//去0
                 if(arrx.charAt(i)=='0') {     
                    }
                 else {
                    arrx=arrx.substring(i, arrx.length());
                    break;
                    }
             }
            return arrx;    
        }
    }
    

    运行超时
    还需要优化,复杂度应该来源于Integer.toOctalString(Integer.valueOf(guo,16));
    接下来尝试自己来构造这个方法

    import java.util.Scanner;
    
    public class Main {
    
        public static void main(String[] args) {
            Scanner sc=new Scanner(System.in);
            int n=sc.nextInt();
            String [] strarr=new String [n];//存储输入
            for(int i=0;i<n;i++) {
                strarr[i]=sc.next();
            }
            
            for(int i=0;i<n;i++) {
                String shuchu=zhuanhuan(strarr[i]);
                System.out.println(shuchu);
            }
        }
        public static String zhuanhuan(String x) {//十六转八
            String arrx="";
             for(int i=0;i<(x.length());i+=3) {
                    String guo;
                    if(x.length()-i-3<0) {
                        guo=x.substring(0,x.length()-i);
                    }
                    else {
                        guo=x.substring(x.length()-i-3,x.length()-i);
                    }
                    String sifu=Integer.toOctalString(Integer.valueOf(guo,16));
                    switch(sifu.length()) {//补零
                    case 4:
                        break;
                    case 3:
                        sifu="0"+sifu;
                        break;
                    case 2:
                        sifu="00"+sifu;
                        break;
                    case 1:
                        sifu="000"+sifu;
                        break;
                    default:
                        break;
                    }
                    arrx=sifu+arrx;//连接字符
                }
             for(int i=0;i<arrx.length();i++) {//去0
                 if(arrx.charAt(i)=='0') {     
                    }
                 else {
                    arrx=arrx.substring(i, arrx.length());
                    break;
                    }
             }
            return arrx;    
        }
        public static String shiliuzhuanten(String str) {
            String chuan= "";
            for(int i=0;i<str.length();i++) {   //遍历各个字符
                char danzifu=str.charAt(i);    
                chuan=chuan+tenzhuantwo(danzifu);//连接二进制字符
            }
            //CHUAN2
            String number="";
            for(int i=0;i<(chuan.length()/3)+1;i++) {
                String guo;
                if(chuan.length()-3*i-3<0) {
                    guo=chuan.substring(0,chuan.length()-3*i);
                }
                else {
                    guo=chuan.substring(chuan.length()-3*i-3,chuan.length()-3*i);
                }
                number=twozhuaneight(guo)+number;
            }
            return number;
        }
        private static char twozhuaneight(String x) {
            int number = 0;
            for(int i=0;i<x.length();i++) {
                char shu=x.charAt(x.length()-1-i);
                switch(shu) {
                case '1':
                    number=(int) (number+Math.pow(2, i));
                    break;
                case'0':
                    number=number;
                    break;
                default:
                    break;
                }
            }
            char cNumber= (char) (number+'0');
            return cNumber;
    
        }
        private static String tenzhuantwo(char danzifu) {
            String hui="";
            switch(danzifu){
            case '0':
                hui="0000";
                break;
            case '1':
                hui="0001";
                break;
            case '2':
                hui="0010";
                break;
            case '3':
                hui="0011";
                break;
            case '4':
                hui="0100";
                break;
            case '5':
                hui="0101";
                break;
            case '6':
                hui="0110";
                break;
            case '7':
                hui="0111";
                break;
            case '8':
                hui="1000";
                break;
            case '9':
                hui="1001";
                break;
            case 'A':
                hui="1010";
                break;
            case 'B':
                hui="1011";
                break;
            case 'C':
                hui="1100";
                break;
            case 'D':
                hui="1101";
                break;
            case 'E':
                hui="1110";
                break;
            case 'F':
                hui="1111";
                break;
            default:
                break;                             //强制转换未考虑其他字符
            }
            return hui;
        }
        
    }
    

    结合第一次提交的方法,超时

    import java.util.Scanner;
    
    public class Main {
        public static void main(String[] args) {
            Scanner sc = new Scanner (System.in);
            int a = sc.nextInt();
            String aa []=new String [a];
            for(int i=0;i<a;i++) {
                aa[i]=sc.next();
            }
            for(int i=0;i<a;i++ ) {
                String shuchu=zhuanhuan(aa[i]);
                System.out.println(shuchu);
            }
            
            
        }
    
        private static String zhuanhuan(String shiliuzhi) {
            String bazhi="";
            String erzhi="";
            for (int i=0;i<shiliuzhi.length();i++) {
                char x = shiliuzhi.charAt(i);
                erzhi=erzhi+zhuanhuan(x);
            }
            
            //erzhi 首未除去0
            bazhi=zhuanba(erzhi);
            
            while(bazhi.substring(0,1).equals("0")&&!bazhi.equals("0")) {
                bazhi=bazhi.substring(1,bazhi.length());
            }
            
            
    //      System.out .println(erzhi);
            return bazhi;
        }
        
           public static String  zhuanba(String chuan) {
                String number="";
                for(int i=0;i<(chuan.length()/3)+1;i++) {
                    String guo;
                    if(chuan.length()-3*i-3<0) {
                        guo=chuan.substring(0,chuan.length()-3*i);
                    }
                    else {
                        guo=chuan.substring(chuan.length()-3*i-3,chuan.length()-3*i);
                    }
    //              System.out.println(guo);
                    number=twozhuanba(guo)+number;
                }
                return number;
            }
           
           private static String twozhuanba(String guo) {
                while(guo.length()<3) {
                    guo="0"+guo;
                }
                String hui ;
    //        System.out.println(guo);
                switch(guo){
                case "000":
                    hui="0";
                    break;
                case "001":
                    hui="1";
                    break;
                case "010":
                    hui="2";
                    break;
                case "011":
                    hui="3";
                    break;
                case "100":
                    hui="4";
                    break;
                case "101":
                    hui="5";
                    break;
                case "110":
                    hui="6";
                    break;
                case "111":
                    hui="7";
                    break;
                default:
                    hui=null;
                    break;                             //强制转换未考虑其他字符
                }
                return hui;
    
            }
           
    
        private static String zhuanhuan(char x) {
            String hui=null;
            switch (x) {
            case '0':
                hui = "0000";
                break; 
            case '1':
                hui = "0001";
                break;
            case '2':
                hui = "0010";
                break;
            case '3':
                hui = "0011";
                break;
            case '4':
                hui = "0100";
                break ;
            case '5':
                hui = "0101";
                break;
            case '6':
                hui = "0110";
                break;
            case '7':
                hui = "0111";
                break;
            case '8':
                hui = "1000";
                break;
            case '9':
                hui = "1001";
                break;
            case 'A':
                hui = "1010";
                break;
            case 'B':
                hui = "1011";
                break;
            case 'C':
                hui = "1100";
                break;
            case 'D':
                hui = "1101";
                break;
            case 'E':
                hui = "1110";
                break;
            case 'F':
                hui = "1111";
                break;
            default:
                hui = null;
                break;  
            }
            return hui;
            
        }
    }
    
    
    
    

    看下测试数据是一个特别巨大的数字

    相关文章

      网友评论

          本文标题:基础练习 十六进制转八进制

          本文链接:https://www.haomeiwen.com/subject/rhqrkqtx.html