您的位置:首页 > 编程语言 > Java开发

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

2017-07-25 07:37 225 查看
题目:

问题描述
  给定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
4000
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 stub
StringBuilder 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 stub
if(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 stub
StringBuilder 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 stub
if(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进制直接输出即可。

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

如各位觉得能优化的地方欢迎共同进步。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  算法 蓝桥杯 JAVA