斐波那契数列(Fibonacci sequence),又称黄金分割数列、因数学家列昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:1、1、2、3、5、8、13、21、34、……在数学上,斐波那契数列以如下被以递推的方法定义:F(1)=1,F(2)=1, F(n)=F(n - 1)+F(n - 2)(n ≥ 3,n ∈ N*)在现代物理、准晶体结构、化学等领域,斐波纳契数列都有直接的应用,为此,美国数学会从 1963 年起出版了以《斐波纳契数列季刊》为名的一份数学杂志,用于专门刊载这方面的研究成果。
用人话来说,斐波那契数列就是由 0 和 1 开始,之后的第n的值就等于n前面一位(n-1)和前面两位(n-2)的值相加 (0不用显示)
//使用递归方式求斐波那契数
public function fb($n){
if( $n <=2){
return 1;
}else{
return fb($n-1) + fb($n-2);
}
}
//使用递推方式求斐波那契数
public function fb2($n){ //
if( $n <=2){
return 1;
}
$t1 = 1;$t2 = 1;
for($i=3;$i<$n;$i++){
$temp = $t1;
$t1 = $t2;
$t2 = $temp + $t2;
}
return $t1 + $t2;
}
//使用数组递推方式求斐波那契数
public function fb3($n){ //
if($n <= 2){
return 1;
}
$arr = [];
$arr[0] = 1;
$arr[1] = 1;
for($i=2;$i<$n;$i++){
$arr[$i] = $arr[$i-1] + $arr[$i-2];
}
return $arr[$n-1];
}
//递归一个小例子:
//菜单栏无限分级(暂定叁级)
public static function listLevel($arr,$level=1,$pid=0){
static $data = [];
if($level>3){return $data;}
foreach ($arr as $v) {
if($pid==$v['pid']){
if($level==1){
$data[] = $v;
}else{
$v['name'] = str_repeat(" ", $level) . "|__" . $v['name'];
$data[] = $v;
}
self::listLevel($arr,$level+1,$v['id']);
}
}
return $data;
}
//基于角色菜单栏无限分级
public static function listRole($arr,$level=1,$pid=0){
$data = [];
if($level>3){return $data;}
foreach ($arr as $v) {
if($pid==$v['pid']){
$v['label'] = $v['name'];
$v['children'] = self::listRole($arr,$level+1,$v['id']);
$data[] = $v;
}
}
return $data;
}
进行性能分析。
明显的可以预测,递归方法,每多一层,就要向下递归两次。 约为 O(2 的N次方) 而递推算法为 O(n),实测代码如下。
/**性能测试。*/
function bench_profile($starttime , $flag = ''){
$endtime = explode(' ',microtime());
$thistime = $endtime[0]+$endtime[1]-($starttime[0]+$starttime[1]);
$thistime = round($thistime,3);
return $flag."-bench:".$thistime." sec";
}
//使用递归算法。
ini_set("max_execution_time" ,3600);
$s = explode(' ',microtime());
echo $this->bench_profile($s )."<br/>";
echo $this->fb1(100); //依次测试上面三种方法 结果如下图
echo $this->bench_profile($s )."<br/>";
die;