蓝桥杯进制转换JAVA

来源:互联网 发布:阿里云多少钱一年 编辑:程序博客网 时间:2024/05/19 14:37

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

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

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

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

样例输入
  2
  39
  123ABC

样例输出
  71
  4435274

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

1. 用已有的函数,因为测试的数据非常大故会超出范围;

已有的函数:(Integer.toBinaryString/toHexString/toOctalString and Integer.valueOf("FFF",16));PS:这些函数以十进制衔接;

2. 3位16进制数等于4位8进制数(转化为二进制看),十六进制 A1  二进制 1010 0001  八进制 (010 100 001)241;

3.当5位十六进制数→二进制数→八进制数,在二进制转换为八进制的时候会出现不够数目,需要在二进制前补“3-二进制数.length()”个零;


初步代码:

import java.util.Scanner;public class Main {public static void main(String[] args){Scanner sc=new Scanner(System.in);int n=sc.nextInt();//String[] st={"000","001","010","011","100","101","110","111"};for(int i=0;i<n;i++){String str=sc.next();String sb=new String();for(int j=0;j<str.length();j++){String str1=Integer.toBinaryString(Integer.valueOf(String.valueOf(str.charAt(j)),16));for(int m=str1.length();m<4;m++){str1="0"+str1;}sb=sb.concat(str1);//二进制字符串}int zeros=3-sb.length()%3;for(int m=0;m<zeros;m++){sb="0"+sb;}for(int m=0;m<sb.length();m+=3){String str2=sb.substring(m,m+3);//for(int o=0;o<8;o++){//if(str2.equals(st[o]))//{//System.out.print(o);//}//}System.out.print(Integer.toOctalString(Integer.valueOf(str2, 2)));}}sc.close();}}


问题:超时

优化:1.取消最后的中间十进制转换,放弃函数,列表直接转换为八进制; 

      2.上面代码注释掉的部分是第一次优化的部分;

优化改正:

import java.util.Scanner;public class Main {public static void main(String[] args){Scanner sc=new Scanner(System.in);int n=sc.nextInt();String[] st={"000","001","010","011","100","101","110","111"};for(int i=0;i<n;i++){String str=sc.next();String sb=new String();for(int j=0;j<str.length();j++){String str1=Integer.toBinaryString(Integer.valueOf(String.valueOf(str.charAt(j)),16));for(int m=str1.length();m<4;m++){str1="0"+str1;}sb=sb.concat(str1);//二进制字符串}int zeros=3-sb.length()%3;for(int m=0;m<zeros;m++){//为八进制做准备补零sb="0"+sb;}String str3=new String();for(int m=0;m<sb.length();m+=3){String str2=sb.substring(m,m+3);for(int o=0;o<8;o++){if(str2.equals(st[o])){str3=str3.concat(Integer.valueOf(o).toString());}}}while(str3.charAt(0)==0){//去掉残留的先导零str3=str3.replaceFirst("[0]", "");}System.out.print(str3);}sc.close();}}

问题:上代码中,加大加粗部分,str3.charAt(0)==30 或者是str3.charAt(0)==0 始终是false,不明白原因,JDK上说charAt()是返回char值,不太明白char值,必应了一下(http://www.cnblogs.com/tian_z/archive/2010/08/06/1793736.html)无论是这个文章里的char值还是ASCII码都不能使判断成立(true)

用charAt()返回的是char值,用codePointAt()会返回ASCII码值的十进制。

上述问题部分可改为:

while(str3.codePointAt(0)==48){//去掉残留的先导零str3=str3.replaceFirst("^0", "");}System.out.print(str3);
就可以去掉先导零了。


尝试用正则表达式和replaceAll在匹配不到时候会产生错误用try catch来弄:

try{str3=str3.replaceAll("^0", "");}catch(Exception e){System.out.print(str3);}
结果:不成功,准备去参考一下别人的代码;

参考结果:正则表达式写的不好。。。应该是

str3=str3.replaceAll("^0+", "");System.out.println(str3);
优化过后代码:

import java.util.Scanner;public class Main {public static void main(String[] args){Scanner sc=new Scanner(System.in);int n=sc.nextInt();String[] st={"000","001","010","011","100","101","110","111"};for(int i=0;i<n;i++){String str=sc.next();String sb=new String();for(int j=0;j<str.length();j++){String str1=Integer.toBinaryString(Integer.valueOf(String.valueOf(str.charAt(j)),16));for(int m=str1.length();m<4;m++){str1="0"+str1;}sb=sb.concat(str1);//二进制字符串}int zeros=3-sb.length()%3;for(int m=0;m<zeros;m++){//为八进制做准备补零sb="0"+sb;}String str3=new String();for(int m=0;m<sb.length();m+=3){String str2=sb.substring(m,m+3);for(int o=0;o<8;o++){if(str2.equals(st[o])){str3=str3.concat(Integer.valueOf(o).toString());}}}str3=str3.replaceAll("^0+", "");System.out.println(str3);}sc.close();}}

结果:依旧超时。。。

继续优化:1.把所有字符串粘接用StringBuilder.append(String arg0),比String.concat(String arg0)的速度要快得多;

import java.util.Scanner;public class Main {public static void main(String[] args){Scanner sc=new Scanner(System.in);int n=sc.nextInt();String[] st={"000","001","010","011","100","101","110","111"};for(int i=0;i<n;i++){String str=sc.next();StringBuilder sb=new StringBuilder();for(int j=0;j<str.length();j++){String str1=Integer.toBinaryString(Integer.valueOf(String.valueOf(str.charAt(j)),16));for(int m=str1.length();m<4;m++){str1="0"+str1;}sb=sb.append(str1);//二进制字符串}int zeros=3-sb.length()%3;for(int m=0;m<zeros;m++){//为八进制做准备补零sb=new StringBuilder("0").append(sb);}StringBuilder str3=new StringBuilder();for(int m=0;m<sb.length();m+=3){String str2=sb.substring(m,m+3);for(int o=0;o<8;o++){if(str2.equals(st[o])){str3=str3.append(Integer.valueOf(o).toString());}}}String str4=str3.toString().replaceAll("^0+", "");System.out.println(str4);}sc.close();}}

结果:可以了

后记改动:

真的是很好玩,进制转换全部使用已有的方法Integer.toBinaryString() 等方法,通过十进制为媒介转换到八进制速度比自己列表用If判断要快

优化代码:

import java.util.Scanner;public class Main {public static void main(String[] args){long start=System.currentTimeMillis();// 记录起始时间try {                                        // 线程睡眠5秒,让运行时间不那么小Thread.sleep(5000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}Scanner sc=new Scanner(System.in);int n=sc.nextInt();for(int i=0;i<n;i++){String str=sc.next();StringBuilder sb=new StringBuilder();for(int j=0;j<str.length();j++){String str1=Integer.toBinaryString(Integer.valueOf(String.valueOf(str.charAt(j)),16));for(int m=str1.length();m<4;m++){str1="0"+str1;}sb=sb.append(str1);//二进制字符串}int zeros=3-sb.length()%3;for(int m=0;m<zeros;m++){//为八进制做准备补零sb=new StringBuilder("0").append(sb);}StringBuilder str3=new StringBuilder();String o=new String();for(int m=0;m<sb.length();m+=3){String str2=sb.substring(m,m+3);o=Integer.toOctalString(Integer.valueOf(String.valueOf(str2), 2));str3=str3.append(o);}String str4=str3.toString().replaceAll("^0+", "");System.out.println(str4);}sc.close();long end=System.currentTimeMillis(); // 记录结束时间System.out.println("用时:"+(end-start));// 相减得出运行时间}}

System.currentTimeMillis() 用来自测程序跑了多久时间


1.String.valueOf(),可以返回各个其他类型的字符串形式,具体看JDK

0 0
原创粉丝点击