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進制。java
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 */