通过基本的进制转换练习后,发现基本的进制转换方法受限于int的大小限制,对于很多大数进制转换无能为力。在学习过程中发现BigDecimal可以很好地应对大数进制转换。
1.BigDecimal涉及到的知识点
add(BigDecimal) | BigDecimal对象中的值相加,然后返回这个对象。 |
multiply(BigDecimal) | BigDecimal对象中的值相乘,然后返回这个对象。 |
divide(BigDecimal) | BigDecimal对象中的值相除,然后返回这个对象。 |
pow(int n) | 返回一个BigDecimal,其值是 (thisn), 被精确计算的幂值,使其具有无限精度。 (参数n必须在范围0到999999999) |
divideAndRemainder(BigDecimal) | 返回一个BigDecimal[ ]数组,第一个数是商,第二个数是余数。 |
compareTo(BigDecimal) | 前比后,比较结果: == 1 前比后大 == 0 前后相等 == -1 前比后小 |
2.解题思路
1.首先输入判断
利用正则表达式判断是否满足十六进制要求。
String regex="[0-9A-F]+";
str.matches(regex)
2.将字符串拆解成为单个字符
char[] ch=str.toCharArray();
3.将单个字符转换成十进制
int x1=Integer.parseInt(String.valueOf(ch[i]),16);
4.按位计算
进制的每一位对应着他本身乘以进制的次方。
BigDecimal x2=new BigDecimal(16).pow(ch.length-i-1).multiply(BigDecimal.valueOf(x1));
5.计算总和
num=num.add(x2);
6.循环判断除8,商覆盖num,余数记录。
while(true){
if(num.compareTo(BigDecimal.valueOf(8)) > 0){
BigDecimal[] results = num.divideAndRemainder(BigDecimal.valueOf(8));
num=results[0];
sb.append(results[1]);
}else {
sb.append(num);
break;
}
}
3.完整代码
import java.math.BigDecimal;
import java.util.Scanner;
public class Demo4 {
public static void main(String[] args) {
/*
*给定n个十六进制正整数,输出它们对应的八进制数。
*/
// String str="123AE";
Scanner sc=new Scanner(System.in);
String regex="[0-9A-F]+";
int n=sc.nextInt();
if(n>=1&&n<=10){
String[] strAll=new String[n];
for(int j=0;j<n;j++){
strAll[j]=sc.next();
}
for(int j=0;j<n;j++){
String str=strAll[j];
if(str.matches(regex)&&str.length()<100000){
BigDecimal num=new BigDecimal(0);
char[] ch=str.toCharArray();
for(int i=ch.length-1;i>=0;i--){
//单个字符转十进制
int x1=Integer.parseInt(String.valueOf(ch[i]),16);
//按位计算
BigDecimal x2=new BigDecimal(16).pow(ch.length-i-1).multiply(BigDecimal.valueOf(x1));
num=num.add(x2);
}
StringBuffer sb=new StringBuffer();
while(true){
if(num.compareTo(BigDecimal.valueOf(8)) > 0){
BigDecimal[] results = num.divideAndRemainder(BigDecimal.valueOf(8));
num=results[0];
sb.append(results[1]);
}else {
sb.append(num);
break;
}
}
System.out.println(sb.reverse().toString());
}
}
}
}
}
缺点:虽然内存用比上一次小了很多,但是时间还是不达标。
补充:BigInteger
构造方法中可以实现进制转换,并且一行代码即可解决进制转换问题。下面是先转十进制,再转8进制。
String x=new BigInteger(str,16).toString(8);
总代码如下:
import java.math.BigInteger;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
String regex="[0-9A-F]+";
int n=sc.nextInt();
if(n>=1&&n<=10){
String[] strAll=new String[n];
for(int j=0;j<n;j++){
strAll[j]=sc.next();
}
for(int j=0;j<n;j++){
String str=strAll[j];
if(str.matches(regex)&&str.length()<100000){
String x=new BigInteger(str,16).toString(8);
System.out.println(x);
}
}
}
}
}
但是:
原因未知,自己测试正确。