有时候我们会遇到这样一种跟数学函数:在非负整数集上定义一个函数f,满足f(0) = 0且f(x) = 2 f(x-1) + x^2 。
这样的函数我们怎么去求呢?我们可以看到:f(1) = 2f(0) + 1^2 = 1;f(2) = 2f(1) +2^2 = 6, f(3) = 2f(2) + 3^2 = 21…….
因此当一个函数用他自己来定义时,我们称之为递归;
代码如下
//
//求n以内的所有质数
//created bu AaronLee_1310 on 2019 05 09
//copyright please @
//
package test_1;
public class main3 {
public static void main(String[] args)
{
int result = f(4);
System.out.println(result);
}
public static int f(int x)
{
if(x == 0)
return 0;
else
return 2 * f(x - 1) + x * x;
//记住java的x^2不表示x的平方,表示x与2求异或
//详情请访问:https://zhidao.baidu.com/question/353388809.html
}
}
请一定注意:java中x^2不表示x的平方,表示的是x与2的异或,见:https://zhidao.baidu.com/question/353388809.html
17 18行处理的是基准情况。即此时函数的值可以直接计算出,而不需要求助递归算法;
注意:使用递归方法要牢记四个基本准则:
1.基准情形。必须要某些基准情形,不需要递归就能解出:如上面的f(0) = 0;
2.不断推进。对于那些需要递归求解的情形,每一次调用都必须使状况朝向一种基准情形推进。
3.设计法则。假设所有递归调用都能运行。
4.合成效益法则。求解一个问题的同一实例,切勿在不同的递归调用各种做重复性的工作。
对于第二点说明:如上个例子中,我们要求f(4)就必须知道f(3),而要知道f(3)我们必须知道否f(2),要知道f(2)我们必须知道f(1),而要知道f(1)我们必须知道f(0),而f(0)是已知的,因此我们必须要使状况朝向基准情形f(0)不断推进。
假设这个时候出现了一点问题。我们把x的值赋为-1,这个时候可知求f(-1)需要知道f(-2),f(-2)就需要知道f(-3)依次往下,我们发现,到后面根本就没有基准情形,因此计算机是算不出来的,这个时候计算机只会占满内存空间,程序崩溃。
至于设计法则和合成效益法则目前我还没有遇到这种情况,以后遇到了一定补上。想了解的建议自行百度。
在举一个错误的例子
public static int bad(int n)
{
if(n == 0)
return 0;
else
return bad(n/3 +1) + n -1 ;
}
当n的取值为1时,返回bad(0 + 1) + n - 1,即bad(1) + n - 1;这个时候计算机还是不知道bad(1) 等于多少,因此他会继续递归,bad(1),一直重复递归,直到计算机崩溃。嗯你们可以试试有什么效果,最后计算机有没有崩溃,cpu有没有燃烧,欢迎来留下评论。
再次举一个简单的例子,希望能够更好的理解递归算法:
//打印输出一个整数,要求一个个打印。
package test_1;
public class main4 {
public static void main(String[] args)
{
printOut(67852);
}
public static void printOut(int n)
{
if( n >= 10)
printOut(n / 10);
System.out.print(n % 10);
}
}
输出结果为:67852;
要求出printOut(67852)就必须先求出printOut(6785),依次往前推到print(6)的时候输出6,再依次输出7852(输出6之后,n变为了67,打印(67 %10 = 7),之后n变为了678,依次打印下去),这个过程不好理解,建议使用eclipse的单步调试看看计算机是怎么一步步输出的。