1. 程式人生 > 其它 >藍橋杯: 給定n個十六進位制正整數,輸出它們對應的八進位制數。

藍橋杯: 給定n個十六進位制正整數,輸出它們對應的八進位制數。

技術標籤:java字串

1.題目
問題描述 給定n個十六進位制正整數,輸出它們對應的八進位制數。
輸入格式
  輸入的第一行為一個正整數n (1<=n<=10)。
  接下來n行,每行一個由09、大寫字母AF組成的字串,表示要轉換的十六進位制正整數,每個十六進位制數長度不超過100000。
輸出格式: 輸出n行,每行為輸入對應的八進位制正整數。
  【注意】 輸入的十六進位制數不會有前導0,比如012A。 輸出的八進位制數也不能有前導0。
樣例輸入
  2
  39
  123ABC
樣例輸出
  71
  4435274
  【提示】
  先將十六進位制數轉換成某進位制數,再由某進位制數轉換成八進位制。

  2.思路

  1. 自己的思路:看了題目提示“先將十六進位制數轉換成某進位制數,再由某進位制數轉換成八進位制。”想的就是先將十六進位制轉成十進位制,再將十進位制轉成八進位制,自己寫了一遍。但是提交過後卻是錯誤零分。
    內聯程式碼片
public class HexToOctal {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int m = sc.nextInt();
		ArrayList<String> s = new ArrayList<String>();
		
		for(int i = 0; i < 2 * m - 1; i++) {
			String a = sc.nextLine();
			if(a.length() == 0) {
				continue;
			}else
			s.add(a); 
		}
		convertToDeciamalAndOctal(s);	
	}
	public static void convertToDeciamalAndOctal(ArrayList<String> s) {
		int[] arr = new int[s.size()];
		
		for(int i = 0; i < s.size(); ++i) {
			arr[i] = Integer.parseInt(s.get(i), 16);
		}
		
		for (int i = 0; i < arr.length; i++) {
			System.out.println(Integer.toOctalString(arr[i]));
		}
		
	}
}
  1. 後面參考了其他博主的文章,意識到了自己的錯誤是“每個十六進位制數長度不超過100000。”稍微大一點的十六進位制連long都無法表示了。此時思路就是將十六進位制先轉成二進位制,再用二進位制轉成八進位制,並且都以字串儲存,這樣避免無法儲存的情況。
    難點體會及注意事項:
    (1)注意從鍵盤獲取資料時, sc.nextLine(); 和 sc.next() 的區別,最好是採用後者,因為我發現用 sc.nextLine()時會將換行符也讀入,導致後面還需單獨處理,而 sc.next()就能遮蔽換行符之類的帶來的影響。
    (2)不斷追加字串時最好使用StringBuffer或者StringBuilder,但是這樣用String接收返回的StringBuffer或者StringBuilder時候就要注意呼叫toString方法,當時沒自己寫的時候看博主的,還認為toString可有可無。
    (3)StringBuffer執行緒不安全但速度快,StringBuilder執行緒安全相對StringBuilder就會慢一點點
    (4) 內聯程式碼片
import java.util.Scanner;

public class HexToOctal_2 {
	//建立全域性變數
	static String[] bin = {"0000","0001","0010","0011","0100","0101","0110","0111",
			"1000","1001","1010","1011","1100","1101","1110","1111"};
	static String[] oct = {"0","1","2","3","4","5","6","7"};

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int m = sc.nextInt();
		String[] a = new String[m];
		for(int i = 0; i < m; ++i) {
			a[i] = sc.next();
		}
		for(int i = 0; i < m; ++i) {
			/*
			 * hexToBin(a[i]).toString()   十六進位制轉二進位制
			 * binToOct(hexToBin(a[i]).toString()).toString() 二進位制轉八進位制 
			 */
			String res1 = binToOct(hexToBin(a[i]).toString()).toString();
			if(res1.startsWith("0") ) {
				System.out.println(res1.substring(1)); 
			} else
				System.out.println(res1);
		}
		
	}
	
	   //十六進位制轉二進位制(取出數值)
	public static StringBuilder hexToBin(String s) {
		StringBuilder sb = new StringBuilder();
		int start = 0;
		int end = 1;//一位16進位制數轉化成思位二進位制數,即 1,2,4,8
		while(end <= s.length()) {
			String str = transformToBin(s.substring(start, end));
			start += 1;
			end += 1;
			sb.append(str);
		}
		return sb;
	}
	//十六進位制轉二進位制(將取出的數字轉化成二進位制)
	public static String transformToBin(String s) {
		String b = null;
		switch(s) {
		case "0": b = bin[0]; break;
		case "1": b = bin[1]; break;
		case "2": b = bin[2]; break;
		case "3": b = bin[3]; break;
		case "4": b = bin[4]; break;
		case "5": b = bin[5]; break;
		case "6": b = bin[6]; break;
		case "7": b = bin[7]; break;
		case "8": b = bin[8]; break;
		case "9": b = bin[9]; break;
		case "A": b = bin[10]; break;
		case "B": b = bin[11]; break;
		case "C": b = bin[12]; break;
		case "D": b = bin[13]; break;
		case "E": b = bin[14]; break;
		case "F": b = bin[15]; break;
		}
		return b;
	}
	
	 //二進位制轉八進位制(取出三個二進位制)1 2 4 = 7
	public static StringBuilder binToOct(String s) {
		StringBuilder sb = new StringBuilder();
		int start = 0;
		int end = 3;
		if(s.length() % 3 == 1) {
			s = "00" + s;
		}
		if(s.length() % 3 == 2) {
			s = "0" + s;
		}
		while(end <= s.length()) {
			String str = transformToOct(s.substring(start, end));
			start += 3;
			end += 3;
			sb.append(str);
		}
		return sb;
	}
     public static String transformToOct(String s) {
    	 String b = new String();
    	 switch(s) {
    	 case "000":  b = oct[0];  break;
    	 case "001":  b = oct[1];  break;
    	 case "010":  b = oct[2];  break;
    	 case "011":  b = oct[3];  break;
    	 case "100":  b = oct[4];  break;
    	 case "101":  b = oct[5];  break;
    	 case "110":  b = oct[6];  break;
    	 case "111":  b = oct[7];  break;
    	 }
    	 return b;
     }

}

  1. 上面的方法寫出來之後感覺還是有點複雜,一百來行程式碼呢,然後我就繼續找啊找,主要也不太看得懂c++的方法,找呀找還真逛到了更簡單的方法,然後迫不及待的提交去測試,啪,滿分通過,神了。API真神奇居然還有BigInteger這東西。

下面展示一些 內聯程式碼片

import java.math.BigInteger;
import java.util.Scanner;

public class HexToOctal_3 {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int m = sc.nextInt();
		String[] a = new String[m];
		for(int i = 0; i < m; ++i) {
			a[i] = sc.next();
		}
		for(int i = 0; i < m; ++i) {
			 System.out.println(new BigInteger(a[i],16).toString(8));
		}

	}
}

我的理解:

  1. BigInteger(a[i],16),16是告訴編譯器a[i]是一個十六進位制的String型別的數,然後讓它轉化成十進位制。
    API:
    在這裡插入圖片描述

  2. toString(8)),將十進位制數轉化成八進位制數。
    API:
    在這裡插入圖片描述

只能感嘆API的偉大了。。。。
參考文章:
1.連結: link.
2.連結: link.

學習心得:神了。又是禿頭的一天