一区二区久久-一区二区三区www-一区二区三区久久-一区二区三区久久精品-麻豆国产一区二区在线观看-麻豆国产视频

PHP 用數組降低程序的時間復雜度

而隨著設備硬件配置的不斷提升,對中小型應用程序來說,對算法的空間復雜度的要求也寬松了不少。不過,在當今 Web2.0 時代,對應用程序的時間復雜度卻有了更高的要求。

什么是算法的時間復雜度呢?概要來說,是指從算法中選取一個能代表算法的原操作,以原操作重復執行的次數作為算法的時間量度。影響時間復雜度的因素有兩個:一是原操作的執行時間,二是原操作因控制結構引起的執行次數。要把算法的時間復雜度降下來,降低原操作的執行次數是較為容易的方法,也是主要方法。本文所講述的方法,是通過巧用 php 的數組,降低原操作的執行次數,從而達到降低算法時間復雜度的需求,和大家分享。

算法的時間量度記作 T(n)=O(f(n)),它表示算法中基本操作重復執行的次數是問題規模 n 的某個函數 f(n),也就是說隨著問題規模 n 的增大,算法執行時間的增長率和 f(n) 的增長率相同。多數情況下,我們把最深層循環內的語句作為原操作來討論算法的時間復雜度,因為它的執行次數和包含它的語句的頻度相同。一般情況下,對一個問題只需選擇一種基本操作來討論算法的時間復雜度即可。有時也需要同時考慮多種基本操作。

在 Web 開發中,通常一個功能的執行時間或響應時間,不僅僅跟服務器的響應能力、處理能力有關,還涉及第三方工具的交互時間,如對數據庫的鏈接時間和對數據進行存取的時間。因而在選定原操作是,需要綜合考慮應用程序各方面的因素,以最大影響程序執行時間的操作為原操作,來衡量算法的時間復雜度。也就是說,需要程序員在編寫代碼的時候,對重要操作的執行時間能有基本的認識。



我們先看一個例子,假設 Web 程序的開發語言是 php,后臺采用 DB2 數據庫,php 通過 PEAR::DB 數據抽象層來實現對數據庫的訪問。

數據庫中有學生表 STUDENTS(見表 1),班級表 CLASSES(見表 2),學生成績表 SCORES(見表 3),需要在 Web 頁面中顯示出本次考試數學成績超過 90 分的同學姓名和所在班級。

表 1. STUDENTS Table

列名描述
SID學號
STUNAME姓名
GENDER性別
AGE年齡
CLASSID班級號
 

表 2. CLASSES Table

列名描述
CLASSID班級號
CLASSNAME班級名
 

表 3. SCORES Table

列名描述
SID學生學號
COURSE學科
SCORE成績
 

根據個人編程習慣的不同,要解決這個問題,通常有兩種做法(訪問數據庫的操作用 PEAR::DB 的方式表示),參看方法 1、2。

[ 方法 1 ]對 STUDENTS, CLASSES, SCORES 三個表做聯合查詢,一次獲取滿足條件的學生信息和班級信息。php 算法描述如下:


				$querystr = "select distinct S.STUNAME as STUNAME,C.CLASSNAME as CLASSNAME ".   "from STUDENTS as S,CLASSES as C,SCORES as R ".   "where S.SID=R.SID and S.CLASSID=C.CLASSID and R.COURSE='Math' ".			"and R.SCORE>=90";		$result = $db2handle->query( $querystr ); //從數據庫中獲取數據while( $row=$result->fetchRow(DB_FETCHMODE_ASSOC) ){ //讀取并顯示數據 echo "StudentName=".$row['STUNAME']."/t ClassName=".$row['CLASSNAME']."/n"; }//Done

[ 方法 2 ]從 SCORES 表中找出滿足條件的學生學號,然后從 STUDENTS 表中查找學生的姓名和班級編碼,最后在 CLASSES 表中獲取班級的名稱。php 算法描述如下:


				$scorestr = "select distinct SID from SCORES where COURSE='Math' and SCORE>=90";$scoredata = $db2handle->query( $scorestr ); //從數據庫中獲取滿足條件的學生學號while( $score=$scoredata->fetchRow(DB_FETCHMODE_ASSOC) ){ //讀取學生的學號,并在STUDENTS表中查找學生的姓名和班級編號 $studentstr = "select STUNAME,CLASSID from STUDENTS where SID='".$score['SID']."'"; $studata =$db2handle->query( $studentstr); $stu=$studata->fetchRow(DB_FETCHMODE_ASSOC); //顯示學生的姓名 echo "StudentName=".$stu['STUNAME']."/t "; //讀去學生的班級編號,并在CLASSES表中查找該學生所在班級名稱 $classstr = "select CLASSNAME from CLASSES where CLASSID='".$stu['CLASSID']."'"; $classdata = $db2handle->query( $classstr); $class=$classdata ->fetchRow(DB_FETCHMODE_ASSOC); //顯示學生的班級 echo "CLASSNAME=".$class['CLASSNAME']."/n";}//end while for getting each student's ID. Done

對于這樣的算法描述,相信大家會有似曾相識的感覺。這也是大多程序員廣泛使用的算法。因為已經習慣了將思維中的算法邏輯直接譯成代碼,而往往沒有時間和心思來斟酌算法的優劣。這里來分析一下這兩種算法的時間復雜度。

因 Web 服務器讀取并顯示數據的時間相對較小,一般在 10ms 的數量級,而從 DB2 數據庫里查詢并獲取數據的時間數量級會是 100ms 的數量級,并且隨查詢數據量的增加而增加。所以查詢數據庫的操作可作為量度時間復雜度的原操作,以 STUDENTS 表和 SCORES 表中的數據量作為問題規模 n( 通常情況下,CLASSES 表的數據量較小且相對穩定 )。

對于方法 1,隨著問題規模 n 的增大,訪問數據庫的次數為常量 1。因而,時間復雜度為 T(n)=O(1)。對于方法 2,假設 SCORES 表中滿足條件的記錄有 m 個,則原操作的執行次數為 m+1。也就是說隨著數據規模 n 的增大,原操作的執行次數成線性增長??梢姇r間復雜度為 T(n)=O(n)。可見,方法 1 的時間復雜度低。

那么方法 1 的問題在哪里?主要因為方法 1 會增大數據庫負載,也就是原操作的執行時間受問題規模 n 的影響比較大。假設 STUDENTS,CLASSES,SCORES 的記錄數分別為 X, Y, Z。那么在執行聯合查詢操作時,在數據庫中會形成一個記錄數為 X*Y*Z 的矩陣,然后在這個矩陣中查找滿足條件的記錄數,最后獲取記錄的 STUNAME 信息和 CLASSNAME。這樣,任何一個表中的數據增加,都會造成矩陣表中記錄的成倍增加。



主要思路 :在所需數據中存在相對簡單且數據量穩定的情況下,利用 php 數組 (Array) 的下標 (Index) 可以為字符串 (String) 的特點,巧妙的將數據臨時存放到數組中。這樣可以通過下標 (Index) 快速獲取所需值,從而降低對數據庫的查詢次數,進而降低算法的時間復雜度。

[ 方法 3 ]從 CLASSES 表中獲取 CLASSID 和 CLASSNAME 的對應關系存放到 ClassArray 一維數組中,從 STUDENTS 表中獲取 SID 和 STUNAME 以及 CLASSID 的對應關系存放到 StuArray 二維數組中。之后從 SCORES 表中找出滿足條件的學生學號,從 StuArray 數組中讀取學生的姓名和班級編號,從 ClassArray 中讀取班級的名稱。php 算法描述如下:


				$ClassArray = Array();$StuArray = Array();$classstr = "select CLASSID,CLASSNAME from CLASSES";$classdata = $db2handle->query( $classstr);while( $class=$classdata ->fetchRow(DB_FETCHMODE_ASSOC) ){ //生成ClassArray數組,下標Index以CLASSID命名,對應的值為CLASSNAME $ClassArray[$class['CLASSID']] = $class['CLASSNAME'];}//end while $ClassArray$stustr="select SID,STUNAME,CLASSID from STUDENTS";$studata = $db2handle->query( $stustr);while( $stu=$studata ->fetchRow(DB_FETCHMODE_ASSOC) ){ //生成StuArray數組,下標Index以SID命名,對應的值為STUNAME和CLASSID $StuArray[$stu ['SID']]['STUNAME'] = $stu['STUNAME']; $StuArray[$stu ['SID']]['CLASSID'] = $stu['CLASSID'];}//end while $StuArray$scorestr = "select distinct SID from SCORES where COURSE='Math' and SCORE>=90";$scoredata = $db2handle->query( $scorestr ); //從數據庫中獲取滿足條件的學生學號while( $score=$scoredata->fetchRow(DB_FETCHMODE_ASSOC) ){ //讀取學生的學號,并從StuArray中讀取學生的姓名,從ClassArray中讀取班級名稱 echo "StudentName=".$StuArray[ $score['SID'] ]['STUNAME']."/t "; echo "CLASSNAME=".$ClassArray[ $StuArray[ $score['SID'] ]['CLASSID'] ]."/n";}//end while for getting each student's ID. Done

改進后方法的時間復雜度仍為 T(n)=O(1)。和方法 1 相比,方法 3 不必擔心因某一個表中的記錄增加而引起的數據庫查詢代價的成倍增加。和方法 2 相比,時間復雜度降低的同時,也沒有影響算法空間復雜度??芍^一舉兩得。

雖然此優化方法簡單易用,但并不是說它是萬能的。使用時需要考慮“度”的問題。假設 STUDENTS 表的數據量很大,那么生成 StuArray 的時候對系統內存的消耗就增加,這樣算法的空間復雜度就會受到影響。另外,當數據量足夠大時,影響算法執行時間的主要因素就發生了變化,需要重新選擇原操作。針對 STUDENTS 表記錄數大,CLASSES 表記錄少且穩定的情景,可以考慮用嵌套查詢和數組相結合的方式,對算法進行優化。這里給出方法 4,以供參考。

[ 方法 4 ]從 CLASSES 表中獲取 CLASSID 和 CLASSNAME 的對應關系存放到 ClassArray 一維數組中。從 SCORES 表中查詢滿足條件的學生學號,作為查詢 STUDENTS 表的查詢條件,獲取學生的 STUNAME 和 CLASSID。之后從 ClassArray 中讀取班級的名稱。php 算法描述如下:


				$ClassArray = Array();$classstr = "select CLASSID,CLASSNAME from CLASSES";$classdata = $db2handle->query( $classstr);while( $class=$classdata ->fetchRow(DB_FETCHMODE_ASSOC) ){ //生成ClassArray數組,下標Index以CLASSID命名,對應的值為CLASSNAME $ClassArray[$class['CLASSID']] = $class['CLASSNAME'];}//end while $ClassArray$stustr = "select STUNAME,CLASSID from STUDENTS where SID in ".   "(select distinct SID from SCORES where COURSE='M' and SCORE>=90)";$studata = $db2handle->query( $stustr); //從數據庫中獲取滿足條件的學生姓名和班級編號while( $stu=$studata ->fetchRow(DB_FETCHMODE_ASSOC) ){ //讀取學生的姓名,并從ClassArray中讀取班級名稱 echo "StudentName=".$stu ['STUNAME']."/t "; echo "CLASSNAME=".$ClassArray[ $stu ['CLASSID'] ]."/n";}//end while for getting each student's Info. Done


方法 3 和方法 4 中引用了數組這個小技巧,巧妙地降低了算法的時間復雜度。在實際應用程序中,算法邏輯要復雜得多,對算法的優化需要綜合考慮多方面的因素。需要提出的是,本文所述的方法不僅適用于 php 應用程序。如果編程語言的數組支持以字符串作為下標,就可以考慮采用本文提出的方法:巧用數組的下標來降低算法的時間復雜度。對于不支持字符串做數組下標的編程語言,可以考慮使用建立哈希表來達到同樣的效果。

php技術PHP 用數組降低程序的時間復雜度,轉載需保留來源!

鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。

主站蜘蛛池模板: 久久夜色国产精品噜噜 | www.色呦呦.com| 在线观看欧美视频 | 中文在线不卡 | 91在线视频观看 | 国语自产精品视频在线区 | 久久综合色婷婷 | 伊人久久综在合线亚洲91 | 久久伊人精品一区二区三区 | 五月天天| 色图影院| 国产自精品在线 | 美女特黄视频 | 国产91精品一区 | 中文字幕一区二区三区有限公司 | 美女网站黄 | 日韩一区二三区无 | 亚洲一区二区三区免费视频 | 亚洲成a人片77777老司机 | 欧美成人性色大片在线观看 | 国产日本一区二区三区 | 精品日本一区二区三区在线观看 | 伊人青草 | 久久se精品一区二区国产 | 国产高清福利91成人 | www.亚洲天堂网 | 四虎国产一区二区三区 | 中文字幕日本一本二本三区 | 欧美高清狂热视频60一70 | 一本大道加勒比久久 | 精品国产品国语在线不卡丶 | 欧美精品v日韩精品v国产精品 | 色悠影院| 国产一区二区三区在线观看免费 | 99re热久久 | 91大神在线精品网址 | 综合五月天堂 | 国产精品免费看 | 蕾丝视频成人★在线观看 | 国产成+人+综合+亚洲不卡 | 一区二区三区在线看 |