看本文之前,看下这个小提示可能会更好哦:
本文使用C++语言递归算法求n!。如果读者想要了解C语言采用递归算法求n!可查看文章“C语言通过递归算法求n的阶乘(1.2)”;如果读者想要了解利用C++类结构实现求n!可查看文章“利用C++类结构的方式求n的阶乘(2)”;
让我们先来过一遍阶乘的概念,“概念清晰”才能更好的进行设计。
一、阶乘的概念
1.什么是阶乘?
阶乘在数学里的定义为:
阶乘是指从1乘以2乘以3乘以4一直乘到所要求的数。
例如:求4的阶乘,则阶乘式是1×2×3×4,得到的积是24,24就是4的阶乘。
2.阶乘的表示方法
任何大于1的自然数n阶乘表示方法: n!=1×2×3×……×n 或 n!=n×(n-1)!
例如:5的阶乘表示为5!,4的阶乘表示为4!,以此类推。
3.特别地:数学里规定0的阶乘为1,即0!=1 。(这个要特别注意)
二、“递归算法”分析
1.递归算法实质
递归算法也即“将原有问题分解为新的问题,而解决问题时又用到了原有问题的解法”。也就是,将问题层层分解为它的简化子集,而最终分解出来的问题,是一个已知解的问题。
例如:求1+2+3+4+5+6+...+100,我们则可以使用递归算法计算。下面就这个例子进行分析,求1+2+...+100的和,也就是从1到100的每个数进行相加,那么我们将这个问题转化为每次两个数进行求和,如100+(99+(98+(97+(……+(1))))),可以定义为:sum=sum(n-1)+n,这样我们只需要一个循环就可以求出结果。当然,也有其他方式,在此只用来作为例题进行说明。
2.递归过程
(1)第1阶段:递推。
将原有问题不断分解为新的子问题,逐渐从未知向已知推进,最终达到已知条件,即递归结束条件,表明递推结束。例如:5!=5x4!,4!=4x3!,3!=3x2!,2!=2x1!,1!=1x0!,0!=1。最初的5!我们是未知的,而最后的0!=1是我们已知条件,因此将未知的问题转化为已知的问题,即“递推”。
(2)第2阶段:回归。
什么是回归?回归也即“从已知条件出发,按递推的逆过程,逐一求值回来,最后到达递归开始处,结束回归阶段,完成整个递归过程”。例如:上述我们求5!最终转为0!,因此我们开始从0!开始求值,因为0!=1是已知的,这样每一步结果我们都是已知的,最终得出5!。“回归也即递推的逆过程”,0!=1,1!=1x0!=1,2!=2x1!=2,3!=3x2!=3x2=6,4!=4x3!=4x6=24,5!=5x4!=5x24=120。
三、程序编写分析
根据“二、递归算法分析”,我们可以得出,递归算法分为“递推、回归”两部分,因此我们进行设计时要考虑到这两方面因素。同时也要考虑0!=1这一特殊情况。
因此,我们定义两个变量,变量1设置为默认值1,用于当参数为0时返回1;变量2用于接收“对推后的回归值”,同时用if-else语句判断,这样便可以实现相应功能,下面我们就进行代码实现。
四、代码实现
代码实现如下所示:
//导入头文件
#include<stdio.h>
#include<iostream>
using namespace std;
//创建factorial函数(用于计算)
int factorial(int value){
int real;//记录值
if(value==0){
real=1; //考虑到特殊情况 0!=1,因此初始值赋为1
}
else{
real=factorial(value-1)*value; //递归计算并记录累积值
}
return real;//返回值
}
//说明:本文代码编译环境为DevC++。
//有的编译器不支持int main,如VC++6.0。将int main改为void main即可
//主函数
int main(){
int value;
int realNumber;//接收结果
cout<<"请输入要求阶乘的正整数:";
cin>>value;
realNumber=factorial(value);//计算
cout<<value<<"的阶乘为: "<<value<<"!="<<realNumber;//输出的时候“!”不能忘记哦
cout<<endl;//换行
return 0;//可有可无,建议添加,不影响程序运行
}
五、代码运行结果
六、哈哈,为加深理解留个题目给你练练手(可忽略)
(1) 题目: 用递归算法计算从n个人中选择k个人组成一个委员会的不同组合数。
(2)代码解析:“我在评论区等你哦”!
七、小结
在上述步骤中,通过明确概念、清晰原理、分析递归算法实质、程序编写分析及代码的实现,完成了通过递归算法求n!,如果感到困惑,不妨多看一遍。
写在最后:
读两遍下来,如果仍然有不清楚的地方,可在评论区留言。
如果你有其他感到困惑的问题,欢迎在评论区留言,让我看到你的问题哦。