问题描述:给定n个十六进制正整数,输出它们对应的八进制数。输入的第一行为一个正整数n (1<=n<=10)。接下来n行,每行一个由0~9、大写字母A~F组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000。
刚开始想着,java中Integer类不是提供了进制的转化方法么,直接将输入的16进制先转化成十进制数,在将十进制数转化为2进制数就好了。但是程序的运行错误,看了别人的思路,发现了问题是:输入的16进制数太大(16进制数的长度不超过100000),造成该类的方法不可用,而且不能存储下这么大的数字,因此只能另找办法。
看了别人的思路,恍然大悟,只能将输入转化为二进制,在将二进制转化为八进制字符串。将其按字符串处理,不用担心数据的存储问题了。
具体步骤:
①将输入的字符串转化成对应的二进制字符串,每个字符转化成对应的二进制占4位,如”10”转化为”00010000”。
②因为8进制数只需要3位来表示,我们要调整字符的位数,具体做法是在字符串最前面添加“0”,直到位数是3的倍数。
③将二进制字符串按3位分别转化为对应的八进制字符串。如”010”转化为2。
下面是我的代码。
import java.util.HashMap;
import java.util.Scanner;
import java.lang.Integer;
public class Main{
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
int n; //个数
int i;
int j;
int k; //循环变量
int num; //临时变量
String out[]; //输出结果数组
String str;
StringBuffer s1 = new StringBuffer(); //转化的二进制字符串
StringBuffer result = new StringBuffer(); //最终的8进制数
HashMap<Character, String> hashMap=new HashMap<Character, String>();
hashMap.put('0', "0000");
hashMap.put('1', "0001");
hashMap.put('2', "0010");
hashMap.put('3', "0011");
hashMap.put('4', "0100");
hashMap.put('5', "0101");
hashMap.put('6', "0110");
hashMap.put('7', "0111");
hashMap.put('8', "1000");
hashMap.put('9', "1001");
hashMap.put('A', "1010");
hashMap.put('B', "1011");
hashMap.put('C', "1100");
hashMap.put('D', "1101");
hashMap.put('E', "1110");
hashMap.put('F', "1111");
n=scanner.nextInt();
out=new String[n];
for ( i= 0; i < n; i++) {
str=scanner.next();
for (j = 0; j < str.length(); j++) {
s1=s1.append(hashMap.get(str.charAt(j)));
}
//补全长度为3的倍数,方便转化成8进制数
while (s1.length()%3!=0) {
s1.insert(0, "0");
}
//取3位子串先将其转化成10进制,在转化成8进制
for (k = 0; k <= s1.length()-3; k=k+3) {
//取3位转化成十进制后在转化为2进制,最后添加到结果字符串后
num=Integer.valueOf(s1.substring(k,k+3), 2);
result=result.append(Integer.toOctalString(num).toString());
}
//如果结果第一个字符是0,删除
if (result.charAt(0)=='0') {
result.deleteCharAt(0);
}
out[i]=result.toString();
//清空stringBuffer
s1.delete(0, s1.length());
result.delete(0, result.length());
}
for (String string : out) {
System.out.println(string);
}
}
}