蓝桥杯练习——十六进制转八进制
问题
【问题描述】
给定n个十六进制正整数,输出它们对应的八进制数。
【输入格式】
输入的第一行为一个正整数n (1<=n<=10)。
接下来n行,每行一个由09、大写字母AF组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000。
【输出格式】
输出n行,每行为输入对应的八进制正整数。
【注意】
输入的十六进制数不会有前导0,比如012A。
输出的八进制数也不能有前导0。
【 样例输入】
2
39
123ABC
【样例输出】
71
4435274
思路
这道题的思路仍然是先把十六进制转化成二进制,再把二进制转化成八进制
但是,这个题我做了三遍,第一遍我以整数的形式存中转的二进制数,结果一看到测试数据我人傻了,那么巨大的数,根本装不下
于是第二遍用字符串做的,虽然能把数据都装下了,但是超时
(超时代码)
import java.util.Scanner;
public class SixttoEightOofT {
static String[] sSixt= {"0000","0001","0010","0011","0100","0101","0110","0111","1000",
"1001","1010","1011","1100","1101","1110","1111"};
static String[] sEigh= {"0","1","2","3","4","5","6","7"};
static String string;
public static String change16(char c) {
String x;
switch (c) {
case '0': {
x=sSixt[0];break;
}
case '1': {
x=sSixt[1];break;
}
case '2': {
x=sSixt[2];break;
}
case '3': {
x=sSixt[3];break;
}
case '4': {
x=sSixt[4];break;
}
case '5': {
x=sSixt[5];break;
}
case '6': {
x=sSixt[6];break;
}
case '7': {
x=sSixt[7];break;
}
case '8': {
x=sSixt[8];break;
}
case '9': {
x=sSixt[9];break;
}
case 'A': {
x=sSixt[10];break;
}
case 'B': {
x=sSixt[11];break;
}
case 'C': {
x=sSixt[12];break;
}
case 'D': {
x=sSixt[13];break;
}
case 'E': {
x=sSixt[14];break;
}
default: {
x=sSixt[15];break;
}
}
return x;
}
public static String change8(String c) {
String s;
switch (c) {
case "000": {
s=sEigh[0];break;
}
case "001": {
s=sEigh[1];break;
}
case "010": {
s=sEigh[2];break;
}
case "011": {
s=sEigh[3];break;
}
case "100": {
s=sEigh[4];break;
}
case "101": {
s=sEigh[5];break;
}
case "110": {
s=sEigh[6];break;
}
default:
s=sEigh[7];break;
}
return s;
}
public static void change(String str) {
char []chSixt=str.toCharArray();
String sTwo=change16(chSixt[0]); //二进制数的字串
int i;
for(i=1;i<chSixt.length;i++) { //对于十六进制数的每一位
sTwo=sTwo+change16(chSixt[i]); //形成二进制字串
}
if(sTwo.length()%3!=0) {
int x=sTwo.length()%3;
for(i=0;i<3-x;i++) {
sTwo="0"+sTwo;
}
}
//System.out.println(sTwo);
int t=sTwo.length()-3;
int len=sTwo.length();
for(i=0;i<len/3-1;i++) { //如果len/3不减1,就会导致字串的前面多加一个‘,’,分割得到的数组前面多一位
sTwo=sTwo.substring(0, t)+","+sTwo.substring(t, sTwo.length());
t-=3;
}
//System.out.print(sTwo);
String[] s3=sTwo.split(",");
//System.out.println(s3.length);
/*for (String string : s3) {
System.out.println(string);
}*/
for(i=0;i<s3.length;i++) {
if(i==0&&change8(s3[0])=="0") {
continue;
}
System.out.print(change8(s3[i]));
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner scanner=new Scanner(System.in);
int n=scanner.nextInt();
String []sSixt1 = new String[10];
int i;
for(i=0;i<n;i++) {
String s=scanner.next();
sSixt1[i]=s;
}
for(i=0;i<n;i++) {
change(sSixt1[i]);
System.out.println();
}
}
}
后来发现是因为String型是不可变的,每次对String的操作都要耗费一定的时间。所以改用StringBuilder做。
代码
import java.util.Scanner;
public class Main {
static String[] sSixt= {"0000","0001","0010","0011","0100","0101","0110","0111","1000",
"1001","1010","1011","1100","1101","1110","1111"};
static String[] sEigh= {"0","1","2","3","4","5","6","7"};
public static String change16(char c) {
String x;
switch (c) {
case '0': {
x=sSixt[0];break;
}
case '1': {
x=sSixt[1];break;
}
case '2': {
x=sSixt[2];break;
}
case '3': {
x=sSixt[3];break;
}
case '4': {
x=sSixt[4];break;
}
case '5': {
x=sSixt[5];break;
}
case '6': {
x=sSixt[6];break;
}
case '7': {
x=sSixt[7];break;
}
case '8': {
x=sSixt[8];break;
}
case '9': {
x=sSixt[9];break;
}
case 'A': {
x=sSixt[10];break;
}
case 'B': {
x=sSixt[11];break;
}
case 'C': {
x=sSixt[12];break;
}
case 'D': {
x=sSixt[13];break;
}
case 'E': {
x=sSixt[14];break;
}
default: {
x=sSixt[15];break;
}
}
return x;
}
public static String change8(String c) {
String s;
switch (c) {
case "000": {
s=sEigh[0];break;
}
case "001": {
s=sEigh[1];break;
}
case "010": {
s=sEigh[2];break;
}
case "011": {
s=sEigh[3];break;
}
case "100": {
s=sEigh[4];break;
}
case "101": {
s=sEigh[5];break;
}
case "110": {
s=sEigh[6];break;
}
default:
s=sEigh[7];break;
}
return s;
}
public static void change(String str) {
char []chSixt=str.toCharArray();
StringBuilder sTwo=new StringBuilder(); //二进制数的字串
sTwo.append(change16(chSixt[0]));
int i;
for(i=1;i<chSixt.length;i++) { //对于十六进制数的每一位
sTwo.append(change16(chSixt[i])); //形成二进制字串
}
if(sTwo.length()%3!=0) { //二进制可以用来分割的字串
int x=sTwo.length()%3;
for(i=0;i<3-x;i++) {
sTwo.insert(0, "0");
}
}
int t=sTwo.length()-3;
//System.out.println(sTwo.toString());
for(i=0;i<sTwo.length();i+=3) {
String string=sTwo.substring(i, i+3);
//System.out.println(string);
if(i==0&&change8(string)=="0")continue;
System.out.print(change8(string));
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
String []sSixt=new String[11];
Scanner scanner=new Scanner(System.in);
int n,i;
n=scanner.nextInt();
for(i=0;i<n;i++) {
String s=scanner.next();
sSixt[i]=s;
}
for(i=0;i<n;i++) {
change(sSixt[i]);
System.out.println();
}
}
}
补充——可变字符串
String的加强版,相当于加一个缓冲区
StringBuilder
运行效率慢,线程安全
StringBuffer
运行效率快,线程不安全
正因如此,单线程一般采用StringBuilder比较好
和String区别
1.运行效率更高
2.更节省内存
常用方法
1 .append(); 追加,相当于往后连接
2 .insert(0,str); 添加,其中0指添加在最前面
3 .replace(start,end,new); 替换
4 .delete(start,end); 清除