斐波那契數列(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;