问题描述
给定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;
}
}
看下测试数据是一个特别巨大的数字
网友评论