递归
一:题目1
将非负十进制整数n转换成b进制。(其中b = 2~16)
二:题目分析
将十进制n转换成任意进制b的方法是:n除以b取余作为转换后的数的最低位,在商不为0的情况下,则商继续除以b,取余作为次低位,直到商为0为止。
思想:
·将十六进制的表示形式,即'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
以字符的形式保存在字符数组s[16]中;
·同时定义一个存放转换后结果的数组num[20];将n%b的结果保存在num[]数组中(方法是:num[i++] = s[n%b];n%b的结果正好对应着它在数组s[]中的位置,然后将s[]数组的值赋给num[]数组,这样就完成了结果的保存);
·最后将结果输出即可。
递归模型:
Transform(0,b);(n=0时结束递归,输出结果)
Transform(int n, int b)
Transform(n/b,b);(n!=0)
递归代码:
void Transform(int n, int b)
1 {
2 char s[16]= {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
3 if(n==0)
4 return;
5 Transform(n/b,b);
6 num[i++] = s[n%b];
7 }
算法执行过程按:将31 转换为16进制
第一次调用 第二次调用 第三次调用
Transform(31, 16) Transform(1, 16) Transform(0, 16)
数组中保存‘F’ 数组中保存‘1’
最后经过循环输出结果。
递归栈:
递归运行的层次 |
运行语句的行号 |
递归工作栈状态 |
说明 |
1 |
1,2,3,5 |
|
有主函数进入第一层递归后,运行至语句(行)5,递归调用下一层 |
2 |
1,2,3,5 |
|
由第一层的语句(行)5进入第二层递归,执行至语句(行)5,进入第三层 |
3 |
1,2,3,4
|
|
第三层递归执行至语句(行)4,退出第三层,返回至第二层语句(行)5 |
2 |
6.7 |
|
执行第二层的语句(行)6,将余数对应在s[]数组的值保存在num[]中,退出第二层,返回至第一层语句(行)5 |
1 |
6,7 |
|
执行第一层的语句(行)6,将余数对应在s[]数组的值保存在num[]中,退出第一层,返回主函数,返回地址0 |
0 |
|
栈空 |
继续运行主函数,输出转换结果 |
三:调试及运行结果
将31转换为16进制
- 将转换后的结果在递归函数中输出的时候,结果不正确(多了一个1)
对其进行调试:(并没有发现有什么问题)
(2)解决办法:将输出写在主函数中
运行结果:
四:转换成非递归
分析:
运用函数Transform(int n, int b),在n不等于0的情况下循环将n%b的余数在数组s[]中对应的字符保存在num[]数组中,num[]数组中是以逆序的形式保存,逆序输出便得到了转换结果。
函数Transform(int n, int b)的代码:
void Transform(int n, int b)
{
char s[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
if(n==0)
{
num[0] = '0';
return;
}
while(n!=0)
{
num[i++] = s[n%b];
n = n/b;
}
}
运行结果:
源程序:
#include<stdio.h>
#include<string.h>
int i = 0;
char num[20];
void Transform(int n, int b)
{
char s[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
if(n==0)
return;
Transform(n/b,b);
num[i++] = s[n%b];
}
/*void Transform(int n, int b)
{
char s[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
if(n==0)
{
num[0] = '0';
return;
}
while(n!=0)
{
num[i++] = s[n%b];
n = n/b;
}
}}*/
void main()
{
int n,b;
int flag = 1;
while(flag)
{
printf("请输入任意十进制正整数:");
scanf("%d",&n);
printf("转换为多少进制:");
scanf("%d",&b);
Transform(n,b);
for(int j=0;j<0;j++)
{
printf("%c",num[j]);
}
/*for(int j=i;j>=0;j--)
{
printf("%c",num[j]);
}*/
/*将数组置空 如果要继续进行转换 保证输出来的数不包含上次转换的数
这种置空是将已经开辟的内存空间里的数值置为'\0'
不能有效置空数值释放空间*/
memset(num,'\0',sizeof(num));
printf("\n");
printf("是否继续转换(是1, 否0):");
scanf("%d",&flag);
}
}