最近在做算法编程题的时候遇到一个十六进制转十进制的算法题,觉得很经典,便将自己能想到的,以及看到的其他人好的做法记录下来,做备忘。
java中的进制表示
/**
* 二进制:0b
* 八进制:0
* 十进制:默认
* 十六进制:0x 或 0X 或 #
*/
@Test
public void testRadix(){
System.out.println("二进制:"+0b11);//3
System.out.println("八进制:"+011);//9
System.out.println("十进制:"+11);//11
System.out.println("十六进制 0x:"+0x11);//17
System.out.println("十六进制 0X:"+0X11);//17
System.out.println("十六进制 #:"+ Integer.decode("#11"));//17 不识别直接打印的形式
}
十六进制转十进制
方法一:采用Integer中自带的方法
/**
* 各种进制(十进制,0x 或 0X 或 # 开头的16进制,0开头的八进制)都能转,
* 自动识别前缀
*/
@Test
public void hex2decByUtil(){
Scanner sc = new Scanner(System.in);
while(sc.hasNextLine()){
String line = sc.nextLine();
System.out.println(Integer.decode(line));
}
}
/**
* 可以转不带进制前缀,指定了字符串所指代进制数的数据
* 可以转2进制~36进制间的所有数据
*/
@Test
public void hex2decByUtil2(){
Scanner sc = new Scanner(System.in);
while(sc.hasNextLine()){
String line = sc.nextLine();
System.out.println(Integer.parseInt(line,16));
}
}
方法二:自己写一个十六进制转十进制
1)规定字母和数字的对应关系
/**
* 带前缀的十六进制转十进制
*/
@Test
public void hex2dec(){
Scanner sc = new Scanner(System.in);
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("A", 10);
map.put("B", 11);
map.put("C", 12);
map.put("D", 13);
map.put("E", 14);
map.put("F", 15);
while(sc.hasNextLine()){
String line = sc.nextLine();
int result = 0;//要求的十进制数
boolean flag = true;
if(line != null && line.toUpperCase().startsWith("0X")){
char[] numChar = line.substring(2).toCharArray();
for (int i = numChar.length-1,j=0; i >= 0; i--) {
int data = 0;//当前位的数值
int position = 1;//当前位置的次方数,用来和当前位的数值相乘
if(map.get(String.valueOf(numChar[i])) != null){
data = map.get(String.valueOf(numChar[i]));
}else if (numChar[i] >= '0' || numChar[i] <= '9'){
data = Integer.parseInt(String.valueOf(numChar[i]));
}else{
flag = false;
break;
}
for(int x = 0; x < j; x++){
position *= 16;
}
result += data*position;
j++;
}
}else {flag = false; }
if(flag){
System.out.println(result);
}else{
System.out.println("数据格式不正确,请重新输入");
}
}
}
2)ASCII码转数字的形式,考虑大数问题
/**
* 考虑大数问题
*/
@Test
public void hex2dec2(){
Scanner sc = new Scanner(System.in);
while(sc.hasNextLine()){
boolean flag = true;
String line = sc.nextLine();
if(line!=null){
BigDecimal result = new BigDecimal(0);
if(line.toUpperCase().startsWith("0X")){
line = line.toUpperCase().substring(2);
int position = line.length();//对应的进制位,从高位到低位
char[] lineChar = line.toCharArray();
for(char i : lineChar){
BigDecimal weight = new BigDecimal(16);//对应进制位的权重
position--;
int numD = i;
if('A' <= i && 'F' >= i){
numD -= 55; //根据ASCII码表中的对应关系,得到对应的数值
}else if('0' <= i && '9' >= i){
numD -= 48;
}else{
flag = false;
break;
}
weight = weight.pow(position);
result = result.add(new BigDecimal(numD).multiply(weight));
}
}else{
flag = false;
}
if(flag){
System.out.println(result);
}else{
System.out.println("数据格式错误,请重新录入");
}
}
}
}