蓝桥杯进制转换JAVA

问题描述
  给定n个十六进制正整数,输出它们对应的八进制数。

输入格式
  输入的第一行为一个正整数n (1<=n<=10)。
  接下来n行,每行一个由0~9、大写字母A~F组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000。

输出格式
  输出n行,每行为输入对应的八进制正整数。

  【注意
  输入的十六进制数不会有前导0,比如012A。
  输出的八进制数也不能有前导0。

样例输入
  2
  39
  123ABC

样例输出
  71
  4435274

  提示
  先将十六进制数转换成某进制数,再由某进制数转换成八进制。

1. 用已有的函数,因为测试的数据非常大故会超出范围;

已有的函数:(Integer.toBinaryString/toHexString/toOctalString and Integer.valueOf("FFF",16));PS:这些函数以十进制衔接;

2. 3位16进制数等于4位8进制数(转化为二进制看),十六进制 A1  二进制 1010 0001  八进制 (010 100 001)241;

3.当5位十六进制数→二进制数→八进制数,在二进制转换为八进制的时候会出现不够数目,需要在二进制前补“3-二进制数.length()”个零;


初步代码:

import java.util.Scanner;

public class Main {	
	public static void main(String[] args){
		Scanner sc=new Scanner(System.in);
		int n=sc.nextInt();
//		String[] st={"000","001","010","011","100","101","110","111"};
		for(int i=0;i<n;i++){
			String str=sc.next();
			String sb=new String();
			for(int j=0;j<str.length();j++){
				
				String str1=Integer.toBinaryString(Integer.valueOf(String.valueOf(str.charAt(j)),16));
				for(int m=str1.length();m<4;m++){
					str1="0"+str1;
				}	
				sb=sb.concat(str1);//二进制字符串
			}
			int zeros=3-sb.length()%3;
			for(int m=0;m<zeros;m++){
				sb="0"+sb;
			}
			for(int m=0;m<sb.length();m+=3){
				String str2=sb.substring(m,m+3);
//				for(int o=0;o<8;o++){
//					if(str2.equals(st[o]))
//					{
//						System.out.print(o);
//					}
//				}
				System.out.print(Integer.toOctalString(Integer.valueOf(str2, 2)));
			}
		}
		sc.close();
	}
}


问题:超时

优化:1.取消最后的中间十进制转换,放弃函数,列表直接转换为八进制; 

      2.上面代码注释掉的部分是第一次优化的部分;

优化改正:

import java.util.Scanner;

public class Main {	
	public static void main(String[] args){
		Scanner sc=new Scanner(System.in);
		int n=sc.nextInt();
		String[] st={"000","001","010","011","100","101","110","111"};
		for(int i=0;i<n;i++){
			String str=sc.next();
			String sb=new String();
			for(int j=0;j<str.length();j++){
				
				String str1=Integer.toBinaryString(Integer.valueOf(String.valueOf(str.charAt(j)),16));
				for(int m=str1.length();m<4;m++){
					str1="0"+str1;
				}	
				sb=sb.concat(str1);//二进制字符串
			}
			int zeros=3-sb.length()%3;
			for(int m=0;m<zeros;m++){//为八进制做准备补零
				sb="0"+sb;
			}
			String str3=new String();
			for(int m=0;m<sb.length();m+=3){
				String str2=sb.substring(m,m+3);
				for(int o=0;o<8;o++){
					if(str2.equals(st[o])){
						str3=str3.concat(Integer.valueOf(o).toString());
						}
					}
			}
			while(str3.charAt(0)==0){//去掉残留的先导零
				str3=str3.replaceFirst("[0]", "");
				}
			System.out.print(str3);
		}
		sc.close();
	}
}

问题:上代码中,加大加粗部分,str3.charAt(0)==30 或者是str3.charAt(0)==0 始终是false,不明白原因,JDK上说charAt()是返回char值,不太明白char值,必应了一下(http://www.cnblogs.com/tian_z/archive/2010/08/06/1793736.html)无论是这个文章里的char值还是ASCII码都不能使判断成立(true)

用charAt()返回的是char值,用codePointAt()会返回ASCII码值的十进制。

上述问题部分可改为:

				while(str3.codePointAt(0)==48){//去掉残留的先导零
					str3=str3.replaceFirst("^0", "");
					}
				System.out.print(str3);
就可以去掉先导零了。


尝试用正则表达式和replaceAll在匹配不到时候会产生错误用try catch来弄:

try{
				str3=str3.replaceAll("^0", "");
			}
			catch(Exception e){
				System.out.print(str3);
			}
结果:不成功,准备去参考一下别人的代码;

参考结果:正则表达式写的不好。。。应该是

			str3=str3.replaceAll("^0+", "");
			System.out.println(str3);
优化过后代码:

import java.util.Scanner;

public class Main {	
	public static void main(String[] args){
		Scanner sc=new Scanner(System.in);
		int n=sc.nextInt();
		String[] st={"000","001","010","011","100","101","110","111"};
		for(int i=0;i<n;i++){
			String str=sc.next();
			String sb=new String();
			for(int j=0;j<str.length();j++){
				
				String str1=Integer.toBinaryString(Integer.valueOf(String.valueOf(str.charAt(j)),16));
				for(int m=str1.length();m<4;m++){
					str1="0"+str1;
				}	
				sb=sb.concat(str1);//二进制字符串
			}
			int zeros=3-sb.length()%3;
			for(int m=0;m<zeros;m++){//为八进制做准备补零
				sb="0"+sb;
			}
			String str3=new String();
			for(int m=0;m<sb.length();m+=3){
				String str2=sb.substring(m,m+3);
				for(int o=0;o<8;o++){
					if(str2.equals(st[o])){
						str3=str3.concat(Integer.valueOf(o).toString());
						}
					}
			}
			str3=str3.replaceAll("^0+", "");
			System.out.println(str3);			
		}
		sc.close();
	}
}	

结果:依旧超时。。。

继续优化:1.把所有字符串粘接用StringBuilder.append(String arg0),比String.concat(String arg0)的速度要快得多;

import java.util.Scanner;

public class Main {	
	public static void main(String[] args){
		Scanner sc=new Scanner(System.in);
		int n=sc.nextInt();
		String[] st={"000","001","010","011","100","101","110","111"};
		for(int i=0;i<n;i++){
			String str=sc.next();
			StringBuilder sb=new StringBuilder();
			for(int j=0;j<str.length();j++){
				
				String str1=Integer.toBinaryString(Integer.valueOf(String.valueOf(str.charAt(j)),16));
				for(int m=str1.length();m<4;m++){
					str1="0"+str1;
				}	
				sb=sb.append(str1);//二进制字符串
			}
			int zeros=3-sb.length()%3;
			for(int m=0;m<zeros;m++){//为八进制做准备补零
				sb=new StringBuilder("0").append(sb);
			}
			StringBuilder str3=new StringBuilder();
			for(int m=0;m<sb.length();m+=3){
				String str2=sb.substring(m,m+3);
				for(int o=0;o<8;o++){
					if(str2.equals(st[o])){
						str3=str3.append(Integer.valueOf(o).toString());
						}
					}
			}
			String str4=str3.toString().replaceAll("^0+", "");
			System.out.println(str4);			
		}
		sc.close();
	}
	
}

结果:可以了

后记改动:

真的是很好玩,进制转换全部使用已有的方法Integer.toBinaryString() 等方法,通过十进制为媒介转换到八进制速度比自己列表用If判断要快

优化代码:

import java.util.Scanner;

public class Main {	
	public static void main(String[] args){
		long start=System.currentTimeMillis();// 记录起始时间
		try {                                        // 线程睡眠5秒,让运行时间不那么小
			Thread.sleep(5000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		Scanner sc=new Scanner(System.in);
		int n=sc.nextInt();
		for(int i=0;i<n;i++){
			String str=sc.next();
			StringBuilder sb=new StringBuilder();
			for(int j=0;j<str.length();j++){
				
				String str1=Integer.toBinaryString(Integer.valueOf(String.valueOf(str.charAt(j)),16));
				for(int m=str1.length();m<4;m++){
					str1="0"+str1;
				}	
				sb=sb.append(str1);//二进制字符串
			}
			int zeros=3-sb.length()%3;
			for(int m=0;m<zeros;m++){//为八进制做准备补零
				sb=new StringBuilder("0").append(sb);
			}
			StringBuilder str3=new StringBuilder();
			String o=new String();
			for(int m=0;m<sb.length();m+=3){
				String str2=sb.substring(m,m+3);
				o=Integer.toOctalString(Integer.valueOf(String.valueOf(str2), 2));
				str3=str3.append(o);
			}
			String str4=str3.toString().replaceAll("^0+", "");
			System.out.println(str4);			
		}
		sc.close();
		long end=System.currentTimeMillis(); // 记录结束时间
		System.out.println("用时:"+(end-start));// 相减得出运行时间
	}
	
}

System.currentTimeMillis() 用来自测程序跑了多久时间


1.String.valueOf(),可以返回各个其他类型的字符串形式,具体看JDK

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值