[蓝桥杯]十六进制转八进制

来源:互联网 发布:视频剪辑专业软件 编辑:程序博客网 时间:2024/05/29 04:03

题目:

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

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

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

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

样例输入
  2
  39
  123ABC

样例输出
  71
  4435274

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



   看似不难,的确不难。但是我提交了7次都不是满分,后来下了他的样例看了一下,居然是10万位的16进制,转换成2进制即40万位数据,只能当做字符串来处理了,看下之前写的:

import java.util.*;public class Main {static Dictionary<String, String> dic=new Hashtable<String, String>();static Dictionary<String, String> dic2=new Hashtable<String, String>();public static void main(String[] args) {Scanner scanner=new Scanner(System.in);int n=scanner.nextInt();dic.put("0", "0000");dic.put("1", "0001");dic.put("2", "0010");dic.put("3", "0011");dic.put("4", "0100");dic.put("5", "0101");dic.put("6", "0110");dic.put("7", "0111");dic.put("8", "1000");dic.put("9", "1001");dic.put("A", "1010");dic.put("B", "1011");dic.put("C", "1100");dic.put("D", "1101");dic.put("E", "1110");dic.put("F", "1111");dic2.put("001", "1");dic2.put("010", "2");dic2.put("011", "3");dic2.put("100", "4");dic2.put("101", "5");dic2.put("110", "6");dic2.put("111", "7");dic2.put("000", "0");for (int i = 0; i < n; i++) {StringBuilder builder=new StringBuilder(scanner.next());fun(builder);}}private static void fun(StringBuilder string) {// TODO Auto-generated method stubStringBuilder s=new StringBuilder();for (int i = 0; i < string.length(); i++) {s.append(dic.get(string.charAt(0)+""));}fun2(s);}private static void fun2(StringBuilder s) {// TODO Auto-generated method stubif(s.length()%3==1){s.insert(0, "00");}else if(s.length()%3==2){s.insert(0, "0");}StringBuilder builder=new StringBuilder();for (int i = s.length()-1; i > 0; i-=3) {String temp=s.charAt(i-2)+""+s.charAt(i-1)+""+s.charAt(i);builder.insert(0, dic2.get(temp));}if(builder.charAt(0)=='0'){builder=builder.deleteCharAt(0);}System.out.println(builder);}}


通过查字典来对转换过来的2进制进行处理,这里用如果不用stringBuilder用string的话 效率非常低,但是这样写还是超时,大概2秒-3秒之间出结果,但是还是慢了,没办法 只有改进。

正确代码:

import java.util.*;public class Main {static Dictionary<String, String> dic=new Hashtable<String, String>();//16进制转2进制对应字典static Dictionary<String, String> dic2=new Hashtable<String, String>();//2进制转8进制对应字典public static void main(String[] args) {Scanner scanner=new Scanner(System.in);int n=scanner.nextInt();dic.put("0", "0000");dic.put("1", "0001");dic.put("2", "0010");dic.put("3", "0011");dic.put("4", "0100");dic.put("5", "0101");dic.put("6", "0110");dic.put("7", "0111");dic.put("8", "1000");dic.put("9", "1001");dic.put("A", "1010");dic.put("B", "1011");dic.put("C", "1100");dic.put("D", "1101");dic.put("E", "1110");dic.put("F", "1111");dic2.put("001", "1");dic2.put("010", "2");dic2.put("011", "3");dic2.put("100", "4");dic2.put("101", "5");dic2.put("110", "6");dic2.put("111", "7");dic2.put("000", "0");//字典数据添加for (int i = 0; i < n; i++) {//n个16进制StringBuilder builder=new StringBuilder(scanner.next());fun(builder);}}private static void fun(StringBuilder string) {// TODO Auto-generated method stubStringBuilder s=new StringBuilder();for (int i = 0; i < string.length(); i++) {s.append(dic.get(string.charAt(i)+""));}fun2(s);//把转换过来的二进制进行处理}private static void fun2(StringBuilder s) {// TODO Auto-generated method stubif(s.length()%3==1)//不足3位补0{s.insert(0, "00");}else if(s.length()%3==2){s.insert(0, "0");}for (int i = 0; i < s.length(); i+=3) {String temp=s.charAt(i)+""+s.charAt(i+1)+""+s.charAt(i+2);if(i==0&&temp.equals("000"))//通过字典找到对应8进制输出continue;System.out.print(dic2.get(temp));}System.out.println();}}
直接输出才是正解。


原理:将2进制作为中间进制,这里用stringbuilder进制尾部追加(切记数据大了勿用string),4个二进制=一个16进制,3个二进制=一个八进制,不足3位向前补0,转换过来的2进制通过字典查询对应8进制直接输出即可。


网上也有写这个题目的,方法也很好,不过我看着并不是很明白。。。。。。。。。


如各位觉得能优化的地方欢迎共同进步。

原创粉丝点击