1. 程式人生 > >利用靜態變數記錄並控制遞迴函式的執行次數

利用靜態變數記錄並控制遞迴函式的執行次數

 static關鍵字

        在PHP的函式內部中,當我們定義一個static變數時,需要對該變數進行初始化賦值且僅初始化一次,由於static修飾的變數是區域性的,該變數僅在函式內部有效,當每次呼叫該函式時,該變數的值都會保留。

        利用這一特性,可以統計出遞迴函式的呼叫次數,並可以做限制,防止未收斂的遞迴函式無限執行下去,造成死迴圈。

        下面可以通過遞迴方法常用的 求斐波那契數列 與 快速排序 做演示:

        斐波那契數列

$num = 10;  
echo "fibonacciSequence($num)的值為:".fibonacciSequence($num);  
echo PHP_EOL;  
  
function fibonacciSequence($num)  
{  
    $limitCount = 1000;  
    static $executeCount = 0;  
    $executeCount++;//static變數在函式內完成初始化後,每次執行該函式變數值都會保留,利用這一特性可以記錄函式呼叫次數  
    echo "函式".__METHOD__."已遞迴執行{$executeCount}次;".PHP_EOL;  
      
    if($executeCount < $limitCount)//遞迴執行次數未超過函式限定次數方可繼續遞迴下去  
    {  
        if($num == 1)  
        {  
            return 1;  
        }  
        else if($num == 2)  
        {  
            return 1;  
        }  
        else  
        {  
            return fibonacciSequence($num - 1) + fibonacciSequence($num - 2);  
        }  
    }  
    else  
    {  
        exit("函式".__METHOD__."已遞迴執行{$executeCount}次,超過限定次數不可再執行。".PHP_EOL);  
    }  
}  
       快速排序
$disorder = array();  
for($i = 0 ; $i<10 ; $i++){  
    $disorder[$i] = rand(1,100);//隨機取10個1-100的數字組成一個待排數列  
}  
echo "待排序的數列為:".implode(',',$disorder);  
echo PHP_EOL;  
$sortArray = quickSort($disorder);  
echo PHP_EOL;  
echo PHP_EOL;  
echo "最終的排序結果為:".implode(',',$sortArray);  
echo PHP_EOL;  
  
function quickSort($disorder)  
{  
    static $executeCount = 0;  
    $executeCount++;  
    echo PHP_EOL;  
    echo "第{$executeCount}次遞迴執行,";  
    echo "待排數列為:".implode(',',$disorder).";";  
  
    if(!is_array($disorder)) return false;//判斷引數是否是一個數組  
      
    $length=count($disorder);  
    if($length <= 1) return $disorder;//遞迴出口:陣列長度為1,直接返回陣列  
      
    $left = array();  
    $right = array();  
    $flagNumber = $disorder[0];//取待排陣列的首個數字作為標杆  
    for($i=1;$i<$length;$i++)  
    {  
        if($disorder[$i] < $flagNumber)  
        {  
            $left[] = $disorder[$i];//將所有比標杆小的數字,放置標杆左邊  
        }  
        else  
        {  
            $right[] = $disorder[$i];//將所有比標杆大的數字,放置標杆右邊  
        }  
    }  
  
    echo '排序結果:{'.implode(',',$left).'},'.$flagNumber.',{'.implode(',',$right).'};';  
  
    $left = quickSort($left);//繼續遞迴呼叫左半部分的待排陣列  
    $right = quickSort($right);  
      
    return array_merge($left,array($flagNumber),$right);//將所有的結果合併  
}  

相關推薦

利用靜態變數記錄控制函式執行次數

 static關鍵字         在PHP的函式內部中,當我們定義一個static變數時,需要對該變數進行初始化賦值且僅初始化一次,由於static修飾的變數是區域性的,該變數僅在函式內部有效,當每次呼叫該函式時,該變數的值都會保留。         利用這一特性

函式靜態變數的疑惑

本帖最後由 hanyj_3000 於 2011-09-02 22:30:25 編輯 以下的函式功能是把一個整數比如 int num = 2345;轉化為字串2345存到陣列buf。用遞迴來寫。對其中的靜態變數i有一大疑問。 C/C++ code ? 1

Python 裝飾器函式 wraps 利用快取查詢原理,加速

# 裝飾器函式 def foo(fn): def wrappers(): print("hello, %s" %fn.__name__) fn() print("bye, %s" %fn.__name__) return wrap

php 函式的三種實現方式 php利用函式實現無限級分類

遞迴函式是我們常用到的一類函式,最基本的特點是函式自身呼叫自身,但必須在呼叫自身前有條件判斷,否則無限無限呼叫下去。實現遞迴函式可以採取什麼方式呢?本文列出了三種基本方式。理解其原來需要一定的基礎知識水品,包括對全域性變數,引用,靜態變數的理解,也需對他們的作用範圍有所理解。遞迴函式也是解決無限級分類的一個很

Python之路-Day07區域性變數與全域性變數,函式

區域性變數和全域性變數的含義 在子程式中定義的變數稱為區域性變數,在程式的一開始定義的變數稱為全域性變數. 全域性變數作用域是整個程式,區域性變數作用域是定義該變數的子程式. 當全域性變數於區域性變數同名時: 在定義區域性變數的子程式內,區域性變數起作用,在其它地方全域性變數起作用.

利用函式呼叫方式,將所輸入的5個字元,以相反順序打印出來

#include<stdio.h> int main() { void dg(char a[],int x); char a[5]; gets(a); dg(a,5); printf("\n"); return 0; } void dg(char a[5],in

Python函式的定義、匿名函式函式的引數、函式呼叫、引數傳遞、變數作用域、呼叫

Python函式: 函式是組織好的,可重複使用的,用來實現單一,或相關聯功能的程式碼段。 Python提供了許多內建函式,比如print()。你也可以自己建立函式,這被叫做使用者自定義函式。 定義函式: 在Python中,定義一個函式要使用def語句,依次寫出函式名、

利用棧實現函式的非計算

題目描述: 棧的實現及棧的基本操作: #include "stdafx.h" #include<stdio.h> #include<stdlib.h> #include<

python函式(全域性變數,區域性變數,作用域,函式,高階函式,匿名函式)

  1.1函式 1.1.1什麼是函式 函式就是程式實現模組化的基本單元,一般實現某一功能的集合。函式名:就相當於是程式程式碼集合的名稱引數:就是函式運算時需要參與運算的值被稱作為引數函式體:程式的某個功能,進行一系列的邏輯運算return 返回值:函式的返回值能表示函式的執行結果或

第四章 php函式(自定義函式變數範圍、引數傳遞,可變函式函式、內建函式)

任何有效的php程式碼都可以作為函式體使用 //例子1 function add($a,$b){ echo $a+$b; } add(10,20); //php頁面顯示30 // 例子2 function add($a,$b){ return $a+$b; //r

謝爾賓斯基三角形(加入拉桿控制)

package 三角形; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Graphics; import java.awt.event.MouseAdapter; import java.awt.event.M

利用預設引數優化函式

        實際上,尾呼叫的優化發生在引擎背後,除非你嘗試優化一個函式,否則無需思考此類問題。遞迴函式是其主要的應用場景,此時尾呼叫優化的效果很顯著。請看下面這個階乘函式        由於在遞迴呼叫前執行了乘法操作,因此當前版本的階乘函式無法被引擎優化。如果n是一個非常

C# 父子選單填充到TreeNode(根據次數設定節點選中狀態)

/// <summary> /// 子節點選中的遞迴次數 /// </summary> static int recursionCount = 0; /// <summary> /// 設定選單到TreeNode /// </summary> ///

一個小工具,利用php把指定目錄檔案上傳到阿里雲OSS

cp2oss(_GALLERY_DIR); function cp2oss($directory) { $mydir = dir($directory); while($file = $mydir->read()) { if(is_dir("$

利用二叉樹的非後序遍歷求解最近公共祖先問題

通過上一篇的部落格我們知道,可以利用棧來實現二叉樹的後序遍歷。其實這裡有一個性質,就是當使用非遞迴後序遍歷時,棧中的元素就是當前節點到根節點的路徑。利用這個規律,我們就可以求解最近公共最先問題了。 演算法 找出兩個節點各自到根節點的路徑。這裡利

Python自學記錄——函式引數和函式

大多數時候,我們呼叫函式時,需要傳入指定的引數,根據我們傳入的引數,函式將返回我們對應引數的結果。在Python定義引數比較簡單,靈活度特別大。除了正常定義的必選引數外,還有預設引數、可變引數、關鍵字引數,使函式定義的介面,不但能處理複雜的引數,還能簡化呼叫者的程式碼。位置引

HTML中的函式使用基礎(函式定義,函式呼叫,函式引數,函式返回值,巢狀函式函式變數作用域,內建函式,其他定義函式的方法)

HTML中的函式使用基礎 函式實質上是一個類似於單獨的邏輯單元的JavaScript程式碼,使用函式可以使程式碼更為簡潔,提供重用性,在JavaScript中,大約有95以上的程式碼是包含在函式中的,由此可見,函式在JavaScript中地位相當重要。 1、函式定義 在

爬蟲實戰(整站爬蟲新浪新聞,按照路徑儲存在本地)

新浪網分類資訊爬蟲 爬取新浪網導航頁所有下所有大類、小類、小類裡的子連結,以及子連結頁面的新聞內容。 效果演示圖: items.py import scrapy import sys reload(sys) sys.setdefaultencoding("utf-8"

十一、Go基礎程式設計:函式函式型別、匿名函式與閉包

1. 遞迴函式 遞迴指函式可以直接或間接的呼叫自身。 遞迴函式通常有相同的結構:一個跳出條件和一個遞迴體。所謂跳出條件就是根據傳入的引數判斷是否需要停止遞迴,而遞迴體則是函式自身所做的一些處理。 //通過迴圈實現1+2+3……+100 func Test01() int { i

函式使用例項

一.建立遞迴陣列 //$fid 父id $v['id'] 子id $v['child'] 子id陣列 //$cate 要迴圈的一維陣列 function digui($cate, $fid = 0){ foreach ($cate as $v)