1 import java.util.Scanner; 2 public class Main { 3 public static void main(String[] args) { 4 new Main().systemScanner(); 5 } 6 public void systemScanner() { 7 Scanner jin = new Scanner(System.in); 8 while (jin.hasNext()) { 9 int length = jin.nextInt(); 10 for (int i = 0; i < length; i++){ 11 String strTmp=jin.next(); 12 tranform(strTmp.toCharArray(), strTmp.length()); 13 } 14 } 15 } 16 /* 17 * 3位16进制等价于4位8进制 18 */ 19 int[] stack=new int[40000]; 20 public void tranform(char[] str, int length) { 21 char[] buff = new char[4]; 22 int top = -1; 23 for (int i = length - 1; i >= 0; i -= 3) { 24 int sum = 0; 25 for (int j = 0; j < 3 && i - j >= 0; j++) {// i-j>=0防止不够三个的情况 26 int tmp = str[i - j] >= '0' && str[i - j] <= '9' ? str[i - j] - '0': str[i - j] - 'A' + 10;//区分是数字,还是字符,进行对应转换 27 sum+=(tmp<<(4*j));//这句很重要,通过这句就可以从16变成10进制了。 28 } 29 stack[++top]=sum;//sum的结果是16进制转化10进制的结果,每3个16进制变成10进制,再变8进制 30 } 31 while(stack[top]==0){//排除前导为0的判断 32 top--; 33 } 34 for(int i=top;i>=0;i--){ 35 String str1=Integer.toOctalString(stack[i]);//从10进制转化成8进制 36 if(i!=top&&str1.length()<4){ 37 //不是最左边的一个,就不用去掉前导0,而默认是去掉0的,所以要进行补会 38 for(int y=0;y<4-str1.length();y++) 39 System.out.print("0"); 40 } 41 System.out.print(str1); 42 } 43 System.out.println(); 44 } 45 }
这种解法的思路是:1位16进制可以代表4位2进制, 1位8进制可以代表3位二进制,得出3位16进制求和入栈输出表示4位8进制,然后出栈输出。由16进制转化为10进制的时候,使用 << 使16进制数转化为8进制。
1 0x11 << 4 => 17; 2 3 /* 4 11的二进制编码是 1011,个位是1 编码是0001,十位是1 编码也是0001。 5 根据位数进行移位运算,个位左移(4*0)位还是0001,十位左移(4*1)位变成00010000 6 */ 7 8 0001 << 4*1 = 00010000; 0001 << 4*0 = 0001; 9 10 /* 11 整个数就变成了00010001 也就是10001 转换为10进制是为17。这里可以看到一个16进 12 制数通过按位数分别左移4*(n-1)位就可以转化为10进制数了。具体的原因是每一个整 13 数左移4位等于这数的二进制表示后面多了4个0,相当于2进制乘法乘了一个二进制10000()。 14 */ 15 1*16^1+1*16^0 = 17; 16 /* 17 10000转化为10进制为16也就是每位乘了16^(n-1)进而把一个16进制数转化为10进制数。 18 */