- 题目分析:
题目:
将非负十进制整数n转换成b进制。(其中b=2~16)
要求:
- 采用递归思想编程解决问题,要求设计出递归模型(递归出口和递归体的函数式)。
- 程序设计风格良好,实现功能测试代码,确保程序的健壮性。
- 画出递归树或者递归栈的调用过程。
- 实现非递归方法。
分析:
将非负十进制数n转化成b进制
- 首先用n对b取余,将余数作为转换后数的最低位
- 将商值赋给n继续对b取余,所得余数作为次低位,直到商值为0
- 余数为10、11、12、13、14、15时用A、B、C、D、E、F代替
- 将余数从最高位到最低位输出即为转化后的进制数。
- 算法设计:
定义递归函数Digui(int n,int b),调用递归Digui(n/b,b)
递归出口:n/b=0
递归体:if(n!=0) {
Digui(n/b,b);
}
递归栈:
以10的二进制为例:
递归运行的层次 | 运行语句的行号 | 递归工作栈状态 (n,b,s) | 说明 |
1 | 7.8.9.10.17.20.21 |
10 2 0 | 由主函数进入第一层递归后,运行至语句10,递归调用下一层 |
2 | 7.9.10.17.20.21 | 5 2 1 10 2 0 | 由第一层的语句10进入第二层递归,执行至语句10,进入第三层 |
3 | 7.9.10.17.20.21 | 2 2 0 5 2 1 10 2 0 | 由第二层的语句10进入第三层递归,执行至语句10,进入第四层 |
4 | 7.9.10.17.20.21 | 1 2 1 2 2 0 5 2 1 10 2 0 | 由第三层的语句10进入第四层递归,执行至语句10,进入第五层 |
5 | 7.9.20.23 | 0 2 1 2 1 2 2 0 5 2 1 10 2 0 | 第五层递归执行至语句23,退出第五层,返回至第四层 |
6 | 23.24 |
| 执行第四层语句23,将保存在s中的余数1输出,返回第三层 |
7 | 23.24 |
| 执行第三层语句23,将保存在s中的余数0输出,返回第二层 |
8 | 23.24 |
| 执行第二层语句23,将保存在s中的余数1输出,返回第一层 |
9 | 23.24 | 10 2 0 | 执行第一层语句23,将保存在s中的余数0输出,退出该层,返回主函数,返回地址为0 |
10 |
| 栈空 | 继续运行主函数 |
- 程序实现:
递归实现:
public void Digui(int n,int b) {
String s=new String();
if(n>0) {
switch(n%b) {
case 10:s="A"+s;break;
case 11:s="B"+s;break;
case 12:s="C"+s;break;
case 13:s="D"+s;break;
case 14:s="E"+s;break;
case 15:s="F"+s;break;
default:s=String.valueOf(n%b)+s;
}
}
if(n!=0) {
Digui(n/b,b);
}
System.out.print(s);
}
非递归实现:
public void FDigui(int n,int b) {
String s=new String();
while(n>0) {
switch(n%b) {
case 10:s="A"+s;break;
case 11:s="B"+s;break;
case 12:s="C"+s;break;
case 13:s="D"+s;break;
case 14:s="E"+s;break;
case 15:s="F"+s;break;
default:s=String.valueOf(n%b)+s;
}
n/=b;
}
System.out.print(s);
}
- 调试及运行结果:
调试:
首次运行成功后出现递归实现得出的结果之前总是有一个0,比如0A,调试后发现当n=0时,s值为0,此时s应该为空,加上if条件判断后再次调试
此时由于n=0不满足条件,s没有值
运行结果:
- 总结:
- 运行过程中遇到转化成的进制数前多出一个0,通过调试发现错误,在对n/b加了if条件判断n>0后运行正确。
- 算法设计时需要注意10~15应转化成A~F。
- 所得余数是一个倒叙的过程,但递归算法是从商等于0时往前推,顺序刚好,但非递归需要考虑倒叙问题,调用String.valueOf(n%b)方法,返回int参数的字符串表示形式,并采用s=String.valueOf(n%b)+s将转化后的进制数以字符串的形式存入s中,直接为正序,避免采用倒叙输出,且采用String对象存入字符串比数组更为简便。
- 测试代码:
package JinzhiChange;
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
int n;
int b;
Scanner sc=new Scanner(System.in);
System.out.println("请输入一个非负整数:");
n=sc.nextInt();
while(true)
{
if(n<0)
{
System.out.println("输入错误!请输入一个非负整数:");
n=sc.nextInt();
}
else
break;
}
System.out.println("请输入转换的进制数(2~16):");
b=sc.nextInt();
while(true)
{
if(b<1||b>16)
{
System.out.println("输入错误!请输入转换的进制数(2~16):");
b=sc.nextInt();
}
else
break;
}
Change c=new Change();
System.out.println("递归实现:");
c.Digui(n,b);
System.out.println("\n非递归实现:");
c.FDigui(n,b);
sc.close();
}
}