第六章递归
题目二借鉴自:
https://blog.csdn.net/u011954296/article/details/51029600
一.题目分析
题目一:将非负十进制整数n转换成b进制。(其中b=2~16)
这道题目要求将十进制分别转化为二进制、八进制和十六进制。递归函数重视寻找递归体和递归的终止条件。
题目二:任何一个正整数都可以用2的幂次方表示。例如:
137=27+23+20。同时约定方次用括号来表示,即ab可表示为a(b)。由此可知,137可表示为: 2(7)+2(3)+2(0)。进一步:7=22+2+20(21用2表示)3=2+20。所以最后137可表示为:
2(2(2)+2+2(0))+2(2+2(0))+2(0)。
先将输入数据137按指数从大到小分为2(7)+2(3)+2(0),然后又将指数按上面同样的方法分为2(2)+2+2(0)、2+2(0)、0,就可分出137的最终结果2(2(2)+2+2(0))+2(2+2(0))+2(0)。非常明显,这道题应该运用递归思想。
二.算法构造
题目一:
递归方法:递归体为ds(s / 2),递归终止条件为s0。其中s为输入的十进制数字。s%x,x为想转换的进制。当s0时,return。此外的情况,执行递归体。在十进制转换为二进制、十进制和十六进制问题上采取同样的方法。注意在十进制装换为十六进制时,若是s % 16 > 9),则需要执行printf("%c", s % 16) - 10 + ‘A’);。这是由于十六进制中09可以用自身表示,而1015需要用‘A’~‘F’表示。
非递归方法:输入十进制数s,s==0时,结束。其他情况执行s/x(x为想转换的进制),且输出s%x,执行此操作的条件为s!=0。所以要借助于do~while()语句。
题目二:如果输入fun(137,0),则输出为2(7)+2(3)+2(0)。 这时,如果对7和3递归处理,则为满足题意的输出。void fun(int n, int r),其中n为操作数,r为递归深度。
三.程序实现
题目一:
#include<stdio.h>
#include<windows.h>
//递归实现十进制转换为二进制
int ds(int s)
{
//s = s / 2; //取模操作
//printf("%d", s % 2); //对/2获得的整数进行取余操作
if (s == 0)
{
return;
}
else
{
ds(s / 2); //递归体
printf("%d", s % 2); //对s取余操作
}
}
int main()
{
int d = 0;
printf("请输入一个十进制数:");
scanf_s("%d", &d);
ds(d);
system("pause");
return 0;
}
//递归实现十进制转换为八进制
int ds(int s)
{
if (s==0)
{
return ;
}
else
{
ds(s / 8);//取模操作
printf("%d", s % 8); //对s进行取余操作
}
}
int main()
{
int d = 0;
printf("请输入一个十进制数:");
scanf_s("%d", &d);
ds(d);
system("pause");
return 0;
}
//递归实现十进制转换为十六进制
int ds(int s)
{
if (s == 0)
{
return;
}
else
{
ds(s / 16);
if (s % 16 > 9)
//printf("%c", s % 16);
printf("%c", (s % 16) - 10 + 'A');
else
printf("%d", s % 16);
//printf("%d", s % 16);
}
}
int main()
{
int d = 0;
printf("请输入一个十进制数:");
scanf_s("%d", &d);
ds(d);
system("pause");
return 0;
}
//非递归实现十进制转换为二进制
int main()
{
int s = 0;
printf("请输入一个十进制数:");
scanf_s("%d", &s);
if (s == 0)
{
return;
}
else
do{
s = s / 2;
printf("%d", s % 2);
}while(s!=0);// 对s取余操作
system("pause");
return 0;
}
//非递归实现十进制转换为八进制
int main()
{
int s = 0;
printf("请输入一个十进制数:");
scanf_s("%d", &s);
if (s == 0)
{
return;
}
else
do {
s = s / 8;
printf("%d", s % 8);
} while (s != 0);// 对s取余操作
system("pause");
return 0;
}
//非递归实现十进制转换为十六进制
int main()
{
int s = 0;
printf("请输入一个十进制数:");
scanf_s("%d", &s);
if (s == 0)
{
return;
}
else
do{
s = s / 16;
if (s % 16 > 9)
printf("%c", (s % 16) - 10 + 'A');
else
printf("%d", s % 16);
} while (s != 0);
system("pause");
return 0;
}
题目二:
void fun(int n, int r)
{
//递归结束,最先输出,不带+号
if (1 == n)
{
//将r表示成0和2
switch (r)
{
//2^0,递归深度为0
case 0: printf("2(0)");
break;
//2^1,递归深度为1
case 1: printf("2");
break;
//2^2,递归深度为2
case 2:printf("2(2)");
break;
//2^r,递归深度为r
default:
printf("2(");
fun(r, 0);
printf(")");
}
}
else
{
//n除以二,递归深度加1
fun(n / 2, r + 1);
//如果模2有余数,则为2^r
if (1 == n % 2)
{
//将r表示成0和2
switch (r)
{
//2^0,递归深度为0
case 0:printf("+2(0)");
break;
//2^1,递归深度为1
case 1:printf("+2");
break;
//2^2,递归深度为2
case 2:printf("+2(2)");
break;
//2^r,递归深度为r
default:
printf("+2(");
fun(r, 0);
printf(")");
}
}
}
}
int main()
{
fun(137, 0);
system("pause");
return 0;
}
此题借鉴自:
https://blog.csdn.net/u011954296/article/details/51029600
四.调用过程
题目一:
上图为十进制转换为二进制的调用过程,十进制转换为八进制和十进制转换为十六进制的过程与上图方法相同。
五.运行结果
题目一:
十进制转化为二进制:
十进制转换为八进制:
十进制转换为十六进制:
题目二:
六.经验总结
在接触到题目一时,首先应该了解到数制之间该如何转换的细节。然后构思递归实现的具体细节。涉及递归处理问题时,必须要将大问题转换为小问题,最重要的是寻找递归终止条件和构造递归体。“除2取余,逆序输出”是十进制转换为二进制数的思想核心,其它进制的转换同理。。非递归实现题目一时,思路不变,对程序稍作改动,并且借助于do~while()语句即可。对于题目二余力不足呐。