标签:出错 产生 数学 代码 程序 blog 故事 传递 编程模型
引子从前有座山,山上有座庙,庙里有个老和尚,老和尚在给小和尚讲故事,故事讲的是从前有座山,山上有座庙,庙里有个老和尚,老和尚在给小和尚讲故事,故事讲的是从前有座山,山上有座庙,庙里有个老和尚,老和尚在给小和尚讲故事,故事讲的是从前有座山,山上有座庙,庙里有个老和尚,老和尚在给小和尚讲故事,故事讲的是从前有座山,山上有座庙,庙里有个老和尚,老和尚在给小和尚讲故事,故事讲的是......
这个例子,如果用java程序来演示,会是这个样子:
public class Hello {
public static void main(String[] args) {
sayStory();
}
static void sayStory(){
System.out.println("从前有座山,山上有座庙,庙里有个老和尚,老和尚在给小和尚讲故事,故事讲的是");
sayStory();
}
}
程序运行结果:
故事在一直讲下去。
看一下java代码中,在方法sayStory()中又调用了sayStory()。
递归,英文为Recursion, 在计算机科学中,递归指得是在函数的定义中使用函数自身。
递归,包含了两个意思:递 和 归。递是只传递下去,归是指归来,也就是说,递归有去也有回。
那么,上面的讲故事的程序,算递归程序吗?
在方法sayStory()中又调用了sayStory(),符合递归的一个条件,即传递,但是,这个程序,没有归来,所以,程序会一直运行下去,直到资源耗尽,程序出错:
因此,这不是个完整的递归程序。
递归要素
首先,递归必须要申明一个函数,且在函数中调用自身。
另外,递归要有明确的终止条件,递归就是有去有回,必然有一个明确的重点,到达这个终点后,就不再往下递,而是开始往回归来。
? 递归的核心思想,就是把规模大的问题转化为规模小的相似的子问题来解决。在函数实现时,因为解决大问题的方法和解决小问题的方法往往是同一个方法,所以就产生了函数调用它自身的情况,这也正是递归的定义所在。
考虑一下,递归的数学模型,很像数学归纳法。数学归纳法适用于将解决的原问题转化为解决它的子问题,而它的子问题又变成子问题的子问题。归纳法解决数学问题一般分为下面3个步骤:
1:步进表达式:问题演算成子问题的表达式
2:结束条件:什么时候可以不再使用步进表达式
3:求解表达式:在结束条件下能够直接计算返回值的表达式
比如,斐波那契数列,使用数学归纳法,3个步骤为:
1: 推导出计算表达式: F(n)=F(n-1)+F(n-2) (n≥3)
2:结束条件:n=1,n=2时
3:求解表达式: F(1)=F(2)=1
明确了递归的数学模型后,我们就要看,如果通过编程来实现递归。一般的,有两种编程模型:
模型一: 先处理问题,然后再往下传递
递归函数(大规模){
if (end_condition){ // 递归终止条件
end;
}else{
solve; // 处理问题
递归函数(小规模); // 分解问题规模,传递下去
}
}
模型二: 在归来的过程中处理问题
递归函数(大规模){
if (end_condition){ // 递归终止条件
end;
}else{
递归函数(小规模); //分解问题规模,传递下去
solve; // 归来,处理问题
}
}
下面,演示一下,使用递归的编程模型,解决斐波那契数列问题。
首先,需要什么一个函数,问题规模为n,问题的结果为一个整数。
则函数可以声明为:int fib(int n)
然后,确定终止条件: n=1,n=2时
3:求解表达式:
F(n)=F(n-1)+F(n-2) (n≥3)
F(1)=1,F(2)=1
则代码如下:
阶乘n!的数学定义: n!=1234…..(n-1)n,并规定 1!=1。
因此,2!=21=2(1!),3!=3(21)=3(2!),
4!=4(321)=4(3!)
5!=5(4321)=54!
根据规律,可以推断出: n!=n*(n-1)!,这就是阶乘的递归公式。
并且可以明确递归的终止条件n=1,终止时的值为1。
下面,想一下,如何用java程序来实现呢?
递归函数原型,可以什么为:int factorial(int n);
则函数的递归调用表达式为: factorial(n)=n* factorial(n-1)
具体代码如下:
public class Hello {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入n:");
int n = sc.nextInt();
int f = factorial(n);
System.out.println("结果是:" + f);
}
static int factorial(int n) {
if (n == 1)
return 1;
else
return n * factorial(n - 1);
}
}
更多案例,请看下一章节。
源码、更多资深讲师相关课程资料、学习笔记请入群后向管理员免费获取,更有专业知识答疑解惑。入群即送价值499元在线课程一份。
QQ群号:560819979
敲门砖(验证信息):高山流水
标签:出错 产生 数学 代码 程序 blog 故事 传递 编程模型
原文地址:http://blog.51cto.com/13477015/2296330