斐波那契数列指的是这样一个数列:1,1,2,3,5,8,13…
这个数列从第3项开始,每一项都等于前两项之和。
那么怎么求得他的第n项及前n项和呢?
一开始想到的是递归。
1.递归算法
<?php
function fbnqn($n){
//如果等于1或2,返回1,结束递归
if($n==1||$n==2){
return 1;
}
else{
//递归处理
return fbnqn($n-1) + fbnqn($n-2);
}
}
function fbnqs($n){
$sum=0;
for($i = 1; $i <= $n; $i ++){
$sum += fbnqn($i);
}
return $sum;
}
echo fbnqs(40);
但是写下来,到输出第38、39项的时候,超过了PHP30s运行时间,因为简单递归代码做了太多次重复计算。
用树形结构分析如下:
比如我要求第5项
5
/ \
4 3
/ \ / \
3 2 2 1
......
这还只是第五项,后面的项会有更多的重复结点,而且重复结点的个数随n的增大而增大,呈指数型增长。
但是如果用数组保存计算出来的值,使用数组中的已有项来计算,就能不做更多的重复计算
于是就换了种不使用递归的简单方法解决这个问题
2.非递归算法
<?php
//两个参数,$n为第n项,$s为是否要求和
function fbnq($n, $s = false){
//数组第一项
$a[1] = 1;
//如果$n等于1,则直接返回数组a
if($n == 1)return $a;
//数组第二项
$a[2] = 1;
if($n == 2){
//如果$s为true,则进行求和
if( $s) $a['sum'] = 2;
//返回数组
return $a;
}
//不等于1和2,那就是大于等于3
else{
//循环解决问题
for($i = 3; $i <= $n; $i ++){
//使用数组保存值
$a[$i] = $a[$i-1] + $a[$i-2];
}
}
//是否需要求和
if ($s) {
//初始化求和数
$sum = 0;
for($j = 1; $j <= $n; $j ++){
//加上数组a的每一项
$sum += $a[$j];
}
//将和存入数组a
$a['sum'] = $sum;
}
//返回数组a
return $a;
}
//echo '<pre>';
//print_r(fbnq(2,true));