试题 基础练习 十六进制转八进制
资源限制
时间限制:1.0s 内存限制:512.0MB
问题描述
给定n个十六进制正整数,输出它们对应的八进制数。
输入格式
输入的第一行为一个正整数n (1<=n<=10)。
接下来n行,每行一个由0~9、大写字母A~F组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000。
输出格式
输出n行,每行为输入对应的八进制正整数。
【注意】
输入的十六进制数不会有前导0,比如012A。
输出的八进制数也不能有前导0。
样例输入
2
39
123ABC
样例输出
71
4435274
【提示】
先将十六进制数转换成某进制数,再由某进制数转换成八进制。
解析
我最开始的思路是将其转为10进制,后转为八进制,我发现这样做的话,这个数字的值会特别的大,16的100000次方这个数就相当的大。Java里的int ,long等数据类型的范围不够用,大数计算的时候效率会非常的低下。如果把这个题换一种思路讨论的话,实际上这是一个字符串处理的问题加一个哈希表,这样处理的效率就高多,时间复杂度大概是10*105=106.此题基本思路是建立哈希表,并将16进制转为2进制,再转为8进制。
具体的实现思路见代码:
package com.lanqiao.mike;
import java.util.HashMap;
import java.util.Scanner;
/**
*
* @Description 建表,然后将16进制转为2进制然后转为8进制
* @author mike
* @version
* @date 2021-3-2914:28:36
*/
public class Class_16转8进制 {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
int n=scanner.nextInt();
//表数据,16进制,四个位表示16种情况
HashMap<Character, String> toByte=new HashMap<>();
toByte.put('0', "0000");
toByte.put('1', "0001");
toByte.put('2', "0010");
toByte.put('3', "0011");
toByte.put('4', "0100");
toByte.put('5', "0101");
toByte.put('6', "0110");
toByte.put('7', "0111");
toByte.put('8', "1000");
toByte.put('9', "1001");
toByte.put('A', "1010");
toByte.put('B', "1011");
toByte.put('C', "1100");
toByte.put('D', "1101");
toByte.put('E', "1110");
toByte.put('F', "1111");
//8进制,3个位8种情况
HashMap<String, Character> toEight=new HashMap<>();
toEight.put("000", '0');
toEight.put("001", '1');
toEight.put("010", '2');
toEight.put("011", '3');
toEight.put("100", '4');
toEight.put("101", '5');
toEight.put("110", '6');
toEight.put("111", '7');
//初始化字符串
String[] str=new String[n];
for (int i = 0; i < str.length; i++) {
str[i]=scanner.next();
}
for (int i = 0; i < n; i++) {//对每个字符串进行处理
StringBuilder ret=new StringBuilder();
StringBuilder res=new StringBuilder();
String a=str[i];
int len=a.length();
for (int j = 0; j < len; j++) {//将16进制转为2进制
char c=a.charAt(j);
res.append(toByte.get(c));
}
//转换为8进制(3个位8种情况,为8进制)
//从后面往前走,最前面的几位可能不足3位,需要进行特殊处理:前面补0凑足三位
for (int k = res.length()-1; k >=0; k-=3) {
String s1=res.substring(k-2<0?0:k-2,k+1);
if (s1.length()<=2) {//不足三位,前面补0
//StringBuilder处理字符串操作高效
StringBuilder s2=new StringBuilder(s1);
while(s2.length()<3) {
s2.insert(0, '0');
}
s1=new String(s2);
}
ret.append(toEight.get(s1));//由于从后往前遍历所以ret存放的数是反的
}
ret=ret.reverse();//反过来
//去除前导0
int j=0;
while(ret.charAt(j)=='0') {
j++;
}
//退出循环后j指向的是非0字符。
//截取j至ret.lenth()-1之间的字符
ret=new StringBuilder(ret.substring(j,ret.length()));
System.out.println(ret);
}
}
}
测试用例如下:像这种测试,只能测试小规模的数据,如要测试大规模的数据需要使用IO流读取文件,并将处理结果写入另一个文件。控制台上只能显示一部分的数据。
5
76
931FA
C9DAB2B36C
248B87D6AE33F9A
62D7183A5D5789E4B2D6
166
2230772
14473254531554
11105607655270637632
142656140722725361171131326
试题 基础练习 十六进制转十进制
资源限制
时间限制:1.0s 内存限制:512.0MB
问题描述
从键盘输入一个不超过8位的正的十六进制数字符串,将它转换为正的十进制数后输出。
注:十六进制数中的10~15分别用大写的英文字母A、B、C、D、E、F表示。
样例输入
FFFF
样例输出
65535
解析
基本思路就是12316=1X162+2X161+3X160。
代码如下:
自己写的具体实现过程。特别注意的是int,long等数据类型的数值范围,int数据只能到Integer.MAXVALUE和Integer.MINVALUE
package com.lanqiao.mike;
import java.util.Scanner;
public class Class_16zhuang10 {
public static void main(String[] args) {
Scanner sc=new Scanner( System.in);
String str=sc.nextLine();
long sum=0;
int len=str.length();
for (int i = 0; i < str.length(); i++) {
char c=str.charAt(i);
if (c>='A'&&c<='F') {
//'A'的ASCII码是65
sum+=(c-55)*(long)Math.pow(16, --len);
}else {
//'0'字符对于的ASCII码是48
sum+=(c-48)*(long)Math.pow(16, --len);
}
}
System.out.println(sum);
// System.out.println((long)Math.pow(2, 32));
// System.out.println((long)Math.pow(2, 31));
// System.out.println((int)Math.pow(2, 31));//超过了int的数据范围
}
}
测试用例:
FFFFFFFF
4294967295
使用jdk内置函数直接转换
package com.lanqiao.mike;
import java.util.Scanner;
public class Class_16zh10_2 {
public static void main(String[] args) {
Scanner sc=new Scanner( System.in);
String str=sc.nextLine();
long sum=Long.parseLong(str, 16);//16进制转为10进制
System.out.println(sum);
}
}
测试用例:
FFFFFFFE
4294967294
试题 基础练习 十进制转十六进制
资源限制
时间限制:1.0s 内存限制:512.0MB
问题描述
十六进制数是在程序设计时经常要使用到的一种整数的表示方式。它有0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F共16个符号,分别表示十进制数的0至15。十六进制的计数方法是满16进1,所以十进制数16在十六进制中是10,而十进制的17在十六进制中是11,以此类推,十进制的30在十六进制中是1E。
给出一个非负整数,将它表示成十六进制的形式。
输入格式
输入包含一个非负整数a,表示要转换的数。0<=a<=2147483647
输出格式
输出这个整数的16进制表示
样例输入
30
样例输出
1E
解析
思路:循环求余,再将所有余数倒过来。如下图所示
10进制转其他进制均是类似的方式。
代码如下:
package com.lanqiao.mike;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
/**
*
* @Description 循环,整除,求余,判断
* @author mike
* @version
* @date 2021-3-2918:51:12
*/
public class Class_10zh16 {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
int a=scanner.nextInt();
StringBuilder sb=new StringBuilder();
Map<Integer, Character> map=new HashMap<>();
map.put(10, 'A');
map.put(11, 'B');
map.put(12, 'C');
map.put(13, 'D');
map.put(14, 'E');
map.put(15, 'F');
if (a==0) {
System.out.println(a);
}else {
while(a!=0) {
int t=a%16;
if (t>=0&&t<=9) {
sb.append(t+"");
}else {
sb.append(map.get(t));
}
a=a/16;
}
//将sb的字符序列反转,就是最终结果
sb=sb.reverse();
System.out.println(sb);
}
// StringBuilder sb=new StringBuilder();
// sb.append(45);
// System.out.println(sb);//处理整数像处理字符串一样
}
}
测试用例:
30
1E
2147483647
7FFFFFFF
最后,如有不当之处,请多指教,感激不尽