蓝桥杯:基础练习 十六进制转八进制

基础练习 十六进制转八进制  
时间限制: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 Binary
				switch (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 Octal
				str = 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()方法进行比较,增加了开销。所以又写了数组实现二进制字符串转换为八进制字符串(以上代码中注释的部分)。经过测试发现数组更是增加了开销,测试结果如下:



你可能感兴趣的:(蓝桥杯)