十进制转b进制
-
问题描述
将非负十进制整数n转换成b进制(其中b=2–16)
-
题目分析
十进制到b进制:输入的十进制数一直除以b直到商为0,逆序取模即转换后的b进制。需要注意的是,二进制到九进制,所得模值都在10以内。十一进制到十六进制,模值在10到15的要用A-F表示。
逆序取模有两种方法,一种是创建一个Stringbuffer对象,用append()方法存储模值,reverse()方法将顺序存入的模倒序;一种是正常使用递归算法,编写代码时要注意输出模值语句和再次调用自身函数语句的顺序,即可得到最终b进制的结果。 -
算法构造
递归出口:以转换为二进制为例,商为0
if(x/2==0) {
System.out.print(x%2);
i++;
}
递归体:商不为0时,输出余数
else{
diverse1(x/2);
System.out.print(x%2);
}
4.代码实现
(1). 递归
package 进制转换;
import java.util.Scanner;
public class 进制转换_递归 {
public static void main(String[] args) {
System.out.print("请输入一个非负十进制数:");
long t1=System.currentTimeMillis();
Scanner input = new Scanner(System.in);
int n = input.nextInt();
if (n <= 0) {
System.out.println("输入数据错误,请重新输入");
} else {
for (int i = 2; i < 17;) {
if (i < 10) {
System.out.print(i - 1 + "." + "十进制转换成" + i + "进制:");
diverse1(n);
i++;//每一次进制转换完成后,i+1进行下个进制的转换
System.out.println("");
} else if (i == 10) {
i++;
} else { //11-16进制模有10 11等数,需要转换为A B等,所以需要重新定义一个方法
System.out.print(i - 2 + "." + "十进制转换成" + i + "进制:");
diverse2(n);
i++;
System.out.println("");
}
}
}
long t2=System.currentTimeMillis();
System.out.println("运行时间为:"+(t2-t1)+"ms");
}
//十进制转换为2-9进制
static int i=2;
public static void diverse1(int x) {
switch(i) {
case 2:
if(x/2==0) {
System.out.print(x%2);
i++;
}else {
diverse1(x/2);
System.out.print(x%2);
}
break;
case 3:
if(x/3==0) {
System.out.print(x%3);
i++;
}else {
diverse1(x/3);
System.out.print(x%3);
}
break;
case 4:
if(x/4==0) {
System.out.print(x%4);
i++;
}else {
diverse1(x/4);
System.out.print(x%4);
}
break;
case 5:
if(x/5==0) {
System.out.print(x%5);
i++;
}else {
diverse1(x/5);
System.out.print(x%5);
}
break;
case 6:
if(x/6==0) {
System.out.print(x%6);
i++;
}else {
diverse1(x/6);
System.out.print(x%6);
}
break;
case 7:
if(x/7==0) {
System.out.print(x%7);
i++;
}else {
diverse1(x/7);
System.out.print(x%7);
}
break;
case 8:
if(x/8==0) {
System.out.print(x%8);
i++;
}else {
diverse1(x/8);
System.out.print(x%8);
}
break;
case 9:
if(x/9==0) {
System.out.print(x%9);
i++;
}else {
diverse1(x/9);
System.out.print(x%9);
}
break;
default:
System.out.println("输入数据错误,请重新输入");
break;
}
}
// 十进制转换为11-16进制
static int j = 11;
public static void diverse2(int y) {
String t;
switch (j) {
case 11:
if (y / 11 == 0) {
System.out.print(y % 11);
j++;
} else {
diverse2(y / 11);
t =String.valueOf(y % 11);
//此处不可用==,==表示字符串的引用是否相等,equals表示字符串的内容是否相等
if(t.equals("10"))
t = "A";
System.out.print(t);
}
break;
case 12:
if (y / 12 == 0) {
System.out.print(y % 12);
j++;
} else {
diverse2(y / 12);
t =String.valueOf(y % 12);
if(t.equals("10")) {
t = "A";
}else if(t.equals("11")) {
t = "B";
}
System.out.print(t);
}
break;
case 13:
if (y / 13 == 0) {
System.out.print(y % 13);
j++;
} else {
diverse2(y / 13);
t =String.valueOf(y % 13);
if(t.equals("10")) {
t = "A";
}else if(t.equals("11")) {
t = "B";
}else if(t.equals("12")) {
t = "C";
}
System.out.print(t);
}
break;
case 14:
if (y / 14 == 0) {
System.out.print(y % 14);
j++;
} else {
diverse2(y / 14);
t =String.valueOf(y % 14);
if(t.equals("10")) {
t = "A";
}else if(t.equals("11")) {
t = "B";
}else if(t.equals("12")) {
t = "C";
}else if(t.equals("13")) {
t = "D";
}
System.out.print(t);
}
break;
case 15:
if (y / 15 == 0) {
System.out.print(y % 15);
j++;
} else {
diverse2(y / 15);
t =String.valueOf(y % 15);
if(t.equals("10")) {
t = "A";
}else if(t.equals("11")) {
t = "B";
}else if(t.equals("12")) {
t = "C";
}else if(t.equals("13")) {
t = "D";
}else if(t.equals("14")) {
t = "E";
}
System.out.print(t);
}
break;
case 16:
if (y / 16 == 0) {
System.out.print(y % 16);
j++;
} else {
diverse2(y / 16);
t =String.valueOf(y % 16);
if(t.equals("10")) { //此处不可用==,==表示字符串的引用是否相等,equals表示字符串的内容是否相等
t = "A";
}else if(t.equals("11")) {
t = "B";
}else if(t.equals("12")) {
t = "C";
}else if(t.equals("13")) {
t = "D";
}else if(t.equals("14")) {
t = "E";
}else if(t.equals("15")) {
t = "F";
}
System.out.print(t);
}
break;
default:
System.out.println("输入数据错误,请重新输入");
break;
}
}
}
(2).非递归
package 进制转换;
import java.util.Scanner;
public class 进制转换_非递归 {
public static void main(String[] args) {
System.out.print("请输入一个非负十进制数:");
long t1 = System.currentTimeMillis();
Scanner input = new Scanner(System.in);
int n = input.nextInt();
transform(n);
long t2=System.currentTimeMillis();
System.out.println("运行时间为:"+(t2-t1)+"ms");
}
// 二进制到十六进制
public static void transform(int m) {
StringBuffer sb = new StringBuffer();
for (int i = 2; i <= 16; i++) {
if (i > 1 && i < 10) { //2--9进制
int x = m;
while (x != 0) {
int y = x % i;
sb.append(y);
x /= i;
}
sb.reverse();
System.out.println("十进制转" + i + "进制:" + sb);
int len = sb.length();
sb.delete(0, len);
} else if (i > 10 && i <= 16) { //11--16进制
int x = m;
while (x != 0) {
int y = x % i;
x /= i;
if (y > 9 && y < 16) {
switch (y) {
case 10:
sb.append('A');
break;
case 11:
sb.append('B');
break;
case 12:
sb.append('C');
break;
case 13:
sb.append('D');
break;
case 14:
sb.append('E');
break;
case 15:
sb.append('F');
break;
}
} else {
sb.append(y);
}
}
sb.reverse();
System.out.println("十进制转" + i + "进制:" + sb);
int len = sb.length();
sb.delete(0, len);
}
}
}
}
-
调试(递归)
输入x=29,i=2,转换为二进制,调用diverse()方法
x变到0后,返回二进制的正确余数
转十一进制,y=2,重新调用diverse2()算法
29转化为十一进制时,第一次除法操作过后商为2,2/11=0,输出余数2
模为14时,转换为E
-
测试及结果
递归算法:
输入29,得到的结果
非递归算法:
7 总结归纳
本次进制转换的递归算法,递归出口是商为0,递归体是输出余数和除以2的操作。敲完代码在调试的过程中,发现对递归多了一些了解。递归出口里的模b输出语句相当于return语句,输出了最后一个余数时,程序回调,执行上一步的递归体,求出上一步的模值,并进行输出。递归算法的执行过程从递归出口(已知的结果)开始向前推进。
在递归算法本身,需要注意10进制以上会存在余数转换为ABCDEF的操作。
因为是递归方法不用考虑余数需要倒序,从递归出口开始得到的自然是一个倒序的结果。
非递归算法解决这道题时,就要考虑到所得余数需要倒序的问题。用数组的话不太好做,可以利用StringBuffer中的reverse()方法倒置已存入的所有余数。存入余数用append()方法。这里同样是十进制以上进制的转换要更改数字为ABCDEF。