基礎練習 十六進位轉八進位 時間限制:1.0s 記憶體限制:512.0MB 問題描述
給定n個十六進位正整數,輸出它們對應的八位元。
輸入格式
輸入的第一行為一個正整數n (1<=n<=10)。
接下來n行,每行一個由0~9、大寫字母A~F組成的字串,表示要轉換的十六進位正整數,每個十六進位數長度不超過100000。
輸出格式
輸出n行,每行為輸入對應的八進位正整數。
【注意】
輸入的十六進位數不會有前置0,比如012A。
輸出的八位元也不能有前置0。
範例輸入
2
39
123ABC
範例輸出
71
4435274
【提示】
先將十六進位數轉換成某進位數,再由某進位數轉換成八進位。
首先,使用Java中封裝的方法先將十六進位轉換為十進位,再將十進位轉換為八進位。
import java.util.Scanner;public class BasicTranformSixteenToEight {public static void transform() {Scanner sc = new Scanner(System.in);int n = sc.nextInt();String[] arry = new String[10];if (n >= 1 && n <= 10) {for (int i = 0; i < n; i++) {String number = sc.next();if (number.length() < 100000) {arry[i] = Integer.toOctalString(Integer.valueOf(number, 16));}}for (int i = 0; i < n; i++) {System.out.println(arry[i]);}}}public static void main(String[] args) { transform();}}
可以實現,但是用於測試資料卻輸出錯誤,主要原因在於Integer長度有限。並不能滿足十六進位字串長度<100000的條件。
之後,自己編寫演算法實現:實現演算法:先將十六進位轉換為二進位,每一位十六進位轉換為4位二進位,對轉換好的二進位字串進行填0校正。若其長度mod 3 = 2,則在其前面填“0”校正,若其長度mod 3 = 1,則在其前面填“00”校正,使其能夠成功轉換為八進位字串,每三位二進位轉換為一位二進位。成功轉化的八進位字串並不符合題目的要求,題目要求輸出無前置0,因此,需要進行去前置0操作。使用substring()獲得八進位字串的前置,並判斷其是否為0,若為0,則去前置0輸出,否則直接輸出。
import java.util.Scanner;public class BasicTranformSixteenToEight {public static void binaryTransform(int n, char[][] arry, String[] arryBinaryStr) {String[] arryOctalStr = new String[10];String str = "";for (int i = 0; i < n; i++) {arryBinaryStr[i] = "";for (int j = 0; j < arry[i].length; j++) {switch (arry[i][j]) {case '0':arryBinaryStr[i] = arryBinaryStr[i] + "0000";break;case '1':arryBinaryStr[i] = arryBinaryStr[i] + "0001";break;case '2':arryBinaryStr[i] = arryBinaryStr[i] + "0010";break;case '3':arryBinaryStr[i] = arryBinaryStr[i] + "0011";break;case '4':arryBinaryStr[i] = arryBinaryStr[i] + "0100";break;case '5':arryBinaryStr[i] = arryBinaryStr[i] + "0101";break;case '6':arryBinaryStr[i] = arryBinaryStr[i] + "0110";break;case '7':arryBinaryStr[i] = arryBinaryStr[i] + "0111";break;case '8':arryBinaryStr[i] = arryBinaryStr[i] + "1000";break;case '9':arryBinaryStr[i] = arryBinaryStr[i] + "1001";break;case 'A':arryBinaryStr[i] = arryBinaryStr[i] + "1010";break;case 'B':arryBinaryStr[i] = arryBinaryStr[i] + "1011";break;case 'C':arryBinaryStr[i] = arryBinaryStr[i] + "1100";break;case 'D':arryBinaryStr[i] = arryBinaryStr[i] + "1101";break;case 'E':arryBinaryStr[i] = arryBinaryStr[i] + "1110";break;case 'F':arryBinaryStr[i] = arryBinaryStr[i] + "1111";break;}}}for (int i = 0; i < n; i++) {if (arryBinaryStr[i].length() % 3 == 1) {arryBinaryStr[i] = "00" + arryBinaryStr[i];} else if (arryBinaryStr[i].length() % 3 == 2) {arryBinaryStr[i] = "0" + arryBinaryStr[i];}arryOctalStr[i] = "";for (int j = 0; j < arryBinaryStr[i].length() / 3; j++) {str = arryBinaryStr[i].substring(j * 3, j * 3 + 3);switch (str) {case "000":arryOctalStr[i] += "0";break;case "001":arryOctalStr[i] += "1";break;case "010":arryOctalStr[i] += "2";break;case "011":arryOctalStr[i] += "3";break;case "100":arryOctalStr[i] += "4";break;case "101":arryOctalStr[i] += "5";break;case "110":arryOctalStr[i] += "6";break;case "111":arryOctalStr[i] += "7";break;}}}for (int i = 0; i < n; i++) {str = arryOctalStr[i].substring(0, 1);if (str.equals("0")) {System.out.println(arryOctalStr[i].substring(1,arryOctalStr[i].length()));} else {System.out.println(arryOctalStr[i]);}}}public static void main(String[] args) {Scanner sc = new Scanner(System.in);int n = sc.nextInt();char[][] arry = new char[10][100000];String[] arryBinaryStr = new String[10];String number;if (n >= 1 && n <= 10) {for (int i = 0; i < n; i++) {number = sc.next();arry[i] = number.toCharArray();}binaryTransform(n, arry, arryBinaryStr);}}}
以上演算法實現後,確實可以成功實現將十六進位轉換為八進位的功能,也滿足了十六進位字串長度<100000的條件,但是卻運行逾時。最終經過尋找資料發現原因主要在於演算法需要多次實現字串拼接,而此演算法中直接使用串連符“+”實現,每次操作都會產生新的String對象,經過改進後利用StringBuilder建立對象,利用append()方法實現字串拼接。
import java.util.Scanner;public class BasicTranformSixteenToEight {public static void toBinaryTransform(int n, char[][] arry,String[] arryBinaryStr) {String[] arryOctalStr = new String[10];String str = "";StringBuilder octalStb = new StringBuilder();StringBuilder binaryStb = new StringBuilder();/*String[] arryOctalBinaryStr = { "000", "001", "010", "011", "100","101", "110", "111" };*/int i, j, k, len;for (i = 0; i < n; i++) {arryBinaryStr[i] = "";arryOctalStr[i] = "";len = arry[i].length;for (j = 0; j < len; j++) { //Convert Hex into Binaryswitch (arry[i][j]) {case '0':binaryStb.append("0000");break;case '1':binaryStb.append("0001");break;case '2':binaryStb.append("0010");break;case '3':binaryStb.append("0011");break;case '4':binaryStb.append("0100");break;case '5':binaryStb.append("0101");break;case '6':binaryStb.append("0110");break;case '7':binaryStb.append("0111");break;case '8':binaryStb.append("1000");break;case '9':binaryStb.append("1001");break;case 'A':binaryStb.append("1010");break;case 'B':binaryStb.append("1011");break;case 'C':binaryStb.append("1100");break;case 'D':binaryStb.append("1101");break;case 'E':binaryStb.append("1110");break;case 'F':binaryStb.append("1111");break;default:break;}}arryBinaryStr[i] = binaryStb.toString();binaryStb = new StringBuilder();if (arryBinaryStr[i].length() % 3 == 1) { // Correct the Binary in order to convert it into Octal.arryBinaryStr[i] = "00" + arryBinaryStr[i];} else if (arryBinaryStr[i].length() % 3 == 2) {arryBinaryStr[i] = "0" + arryBinaryStr[i];}len = arryBinaryStr[i].length() / 3;for (j = 0; j < len; j++) { //Convert Binary into Octalstr = arryBinaryStr[i].substring(j * 3, j * 3 + 3);/*for (k = 0; k <= 7; k++) {if (str.equals(arryOctalBinaryStr[k])) {octalStb.append(k);}}*/switch (str) {case "000":octalStb.append("0");break;case "001":octalStb.append("1");break;case "010":octalStb.append("2");break;case "011":octalStb.append("3");break;case "100":octalStb.append("4");break;case "101":octalStb.append("5");break;case "110":octalStb.append("6");break;case "111":octalStb.append("7");break;}}arryOctalStr[i] = octalStb.toString();octalStb = new StringBuilder();str = arryOctalStr[i].substring(0, 1);if (str.equals("0")) { // Remove the first zero and print Octal.System.out.println(arryOctalStr[i].substring(1,arryOctalStr[i].length()));} else { System.out.println(arryOctalStr[i]);}}}public static void main(String[] args) {Scanner sc = new Scanner(System.in);int n = sc.nextInt();char[][] arry = new char[10][100000];String[] arryBinaryStr = new String[10];String number;if (n >= 1 && n <= 10) {for (int i = 0; i < n; i++) {number = sc.next();arry[i] = number.toCharArray();}toBinaryTransform(n, arry, arryBinaryStr);}}}進過改進後的演算法測試成功,已耗用時間大大縮短。
在轉換為八進位時,首先直接將String用於switch進行比較,轉換。在網上查到switch只支援int char byte short,而String不能作用於switch語句,其String用於switch真正的實現是將其轉換為了hashCode(返回int類型),利用equals()方法進行比較,增加了開銷。所以又寫了數組實現二進位字串轉換為八進位字串(以上代碼中注釋的部分)。經過測試發現數組更是增加了開銷,測試結果如下: