国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

Home php教程 php手冊(cè) PHP 用數(shù)組降低程序的時(shí)間復(fù)雜度

PHP 用數(shù)組降低程序的時(shí)間復(fù)雜度

Jun 13, 2016 pm 12:20 PM
php the complexity right app promote array time use of hardware program equipment Configuration reduce along with

而隨著設(shè)備硬件配置的不斷提升,對(duì)中小型應(yīng)用程序來說,對(duì)算法的空間復(fù)雜度的要求也寬松了不少。不過,在當(dāng)今 Web2.0 時(shí)代,對(duì)應(yīng)用程序的時(shí)間復(fù)雜度卻有了更高的要求。

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

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

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



我們先看一個(gè)例子,假設(shè) Web 程序的開發(fā)語言是 PHP,后臺(tái)采用 DB2 數(shù)據(jù)庫,PHP 通過 PEAR::DB 數(shù)據(jù)抽象層來實(shí)現(xiàn)對(duì)數(shù)據(jù)庫的訪問。

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

表 1. STUDENTS Table

列名 描述
SID 學(xué)號(hào)
STUNAME 姓名
GENDER 性別
AGE 年齡
CLASSID 班級(jí)號(hào)
?

表 2. CLASSES Table

列名 描述
CLASSID 班級(jí)號(hào)
CLASSNAME 班級(jí)名
?

表 3. SCORES Table

列名 描述
SID 學(xué)生學(xué)號(hào)
COURSE 學(xué)科
SCORE 成績(jī)
?

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

[ 方法 1 ]對(duì) STUDENTS, CLASSES, SCORES 三個(gè)表做聯(lián)合查詢,一次獲取滿足條件的學(xué)生信息和班級(jí)信息。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 ); //從數(shù)據(jù)庫中獲取數(shù)據(jù)
while( $row=$result->fetchRow(DB_FETCHMODE_ASSOC) ){
 //讀取并顯示數(shù)據(jù)
 echo "StudentName=".$row['STUNAME']."\t ClassName=".$row['CLASSNAME']."\n"; 
}//Done

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


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

對(duì)于這樣的算法描述,相信大家會(huì)有似曾相識(shí)的感覺。這也是大多程序員廣泛使用的算法。因?yàn)橐呀?jīng)習(xí)慣了將思維中的算法邏輯直接譯成代碼,而往往沒有時(shí)間和心思來斟酌算法的優(yōu)劣。這里來分析一下這兩種算法的時(shí)間復(fù)雜度。

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

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

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



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

[ 方法 3 ]從 CLASSES 表中獲取 CLASSID 和 CLASSNAME 的對(duì)應(yīng)關(guān)系存放到 ClassArray 一維數(shù)組中,從 STUDENTS 表中獲取 SID 和 STUNAME 以及 CLASSID 的對(duì)應(yīng)關(guān)系存放到 StuArray 二維數(shù)組中。之后從 SCORES 表中找出滿足條件的學(xué)生學(xué)號(hào),從 StuArray 數(shù)組中讀取學(xué)生的姓名和班級(jí)編號(hào),從 ClassArray 中讀取班級(jí)的名稱。PHP 算法描述如下:


				
$ClassArray = Array();
$StuArray = Array();
$classstr = "select CLASSID,CLASSNAME from CLASSES";
$classdata = $db2handle->query( $classstr);
while( $class=$classdata ->fetchRow(DB_FETCHMODE_ASSOC) ){
 //生成ClassArray數(shù)組,下標(biāo)Index以CLASSID命名,對(duì)應(yīng)的值為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數(shù)組,下標(biāo)Index以SID命名,對(duì)應(yīng)的值為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 ); 
//從數(shù)據(jù)庫中獲取滿足條件的學(xué)生學(xué)號(hào)
while( $score=$scoredata->fetchRow(DB_FETCHMODE_ASSOC) ){
 //讀取學(xué)生的學(xué)號(hào),并從StuArray中讀取學(xué)生的姓名,從ClassArray中讀取班級(jí)名稱
 echo "StudentName=".$StuArray[ $score['SID'] ]['STUNAME']."\t ";
 echo "CLASSNAME=".$ClassArray[ $StuArray[ $score['SID'] ]['CLASSID'] ]."\n";
}//end while for getting each student's ID. Done

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

雖然此優(yōu)化方法簡(jiǎn)單易用,但并不是說它是萬能的。使用時(shí)需要考慮“度”的問題。假設(shè) STUDENTS 表的數(shù)據(jù)量很大,那么生成 StuArray 的時(shí)候?qū)ο到y(tǒng)內(nèi)存的消耗就增加,這樣算法的空間復(fù)雜度就會(huì)受到影響。另外,當(dāng)數(shù)據(jù)量足夠大時(shí),影響算法執(zhí)行時(shí)間的主要因素就發(fā)生了變化,需要重新選擇原操作。針對(duì) STUDENTS 表記錄數(shù)大,CLASSES 表記錄少且穩(wěn)定的情景,可以考慮用嵌套查詢和數(shù)組相結(jié)合的方式,對(duì)算法進(jìn)行優(yōu)化。這里給出方法 4,以供參考。

[ 方法 4 ]從 CLASSES 表中獲取 CLASSID 和 CLASSNAME 的對(duì)應(yīng)關(guān)系存放到 ClassArray 一維數(shù)組中。從 SCORES 表中查詢滿足條件的學(xué)生學(xué)號(hào),作為查詢 STUDENTS 表的查詢條件,獲取學(xué)生的 STUNAME 和 CLASSID。之后從 ClassArray 中讀取班級(jí)的名稱。PHP 算法描述如下:


				
$ClassArray = Array();
$classstr = "select CLASSID,CLASSNAME from CLASSES";
$classdata = $db2handle->query( $classstr);
while( $class=$classdata ->fetchRow(DB_FETCHMODE_ASSOC) ){
 //生成ClassArray數(shù)組,下標(biāo)Index以CLASSID命名,對(duì)應(yīng)的值為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); 
//從數(shù)據(jù)庫中獲取滿足條件的學(xué)生姓名和班級(jí)編號(hào)
while( $stu=$studata ->fetchRow(DB_FETCHMODE_ASSOC) ){
 //讀取學(xué)生的姓名,并從ClassArray中讀取班級(jí)名稱
 echo "StudentName=".$stu ['STUNAME']."\t ";
 echo "CLASSNAME=".$ClassArray[ $stu ['CLASSID'] ]."\n";
}//end while for getting each student's Info. Done


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

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undress AI Tool

Undress AI Tool

Undress images for free

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

How to access a character in a string by index in PHP How to access a character in a string by index in PHP Jul 12, 2025 am 03:15 AM

In PHP, you can use square brackets or curly braces to obtain string specific index characters, but square brackets are recommended; the index starts from 0, and the access outside the range returns a null value and cannot be assigned a value; mb_substr is required to handle multi-byte characters. For example: $str="hello";echo$str[0]; output h; and Chinese characters such as mb_substr($str,1,1) need to obtain the correct result; in actual applications, the length of the string should be checked before looping, dynamic strings need to be verified for validity, and multilingual projects recommend using multi-byte security functions uniformly.

How Do Generators Work in PHP? How Do Generators Work in PHP? Jul 11, 2025 am 03:12 AM

AgeneratorinPHPisamemory-efficientwaytoiterateoverlargedatasetsbyyieldingvaluesoneatatimeinsteadofreturningthemallatonce.1.Generatorsusetheyieldkeywordtoproducevaluesondemand,reducingmemoryusage.2.Theyareusefulforhandlingbigloops,readinglargefiles,or

How to prevent session hijacking in PHP? How to prevent session hijacking in PHP? Jul 11, 2025 am 03:15 AM

To prevent session hijacking in PHP, the following measures need to be taken: 1. Use HTTPS to encrypt the transmission and set session.cookie_secure=1 in php.ini; 2. Set the security cookie attributes, including httponly, secure and samesite; 3. Call session_regenerate_id(true) when the user logs in or permissions change to change to change the SessionID; 4. Limit the Session life cycle, reasonably configure gc_maxlifetime and record the user's activity time; 5. Prohibit exposing the SessionID to the URL, and set session.use_only

How to URL encode a string in PHP with urlencode How to URL encode a string in PHP with urlencode Jul 11, 2025 am 03:22 AM

The urlencode() function is used to encode strings into URL-safe formats, where non-alphanumeric characters (except -, _, and .) are replaced with a percent sign followed by a two-digit hexadecimal number. For example, spaces are converted to signs, exclamation marks are converted to!, and Chinese characters are converted to their UTF-8 encoding form. When using, only the parameter values ??should be encoded, not the entire URL, to avoid damaging the URL structure. For other parts of the URL, such as path segments, the rawurlencode() function should be used, which converts the space to . When processing array parameters, you can use http_build_query() to automatically encode, or manually call urlencode() on each value to ensure safe transfer of data. just

PHP get the first N characters of a string PHP get the first N characters of a string Jul 11, 2025 am 03:17 AM

You can use substr() or mb_substr() to get the first N characters in PHP. The specific steps are as follows: 1. Use substr($string,0,N) to intercept the first N characters, which is suitable for ASCII characters and is simple and efficient; 2. When processing multi-byte characters (such as Chinese), mb_substr($string,0,N,'UTF-8'), and ensure that mbstring extension is enabled; 3. If the string contains HTML or whitespace characters, you should first use strip_tags() to remove the tags and trim() to clean the spaces, and then intercept them to ensure the results are clean.

PHP get the last N characters of a string PHP get the last N characters of a string Jul 11, 2025 am 03:17 AM

There are two main ways to get the last N characters of a string in PHP: 1. Use the substr() function to intercept through the negative starting position, which is suitable for single-byte characters; 2. Use the mb_substr() function to support multilingual and UTF-8 encoding to avoid truncating non-English characters; 3. Optionally determine whether the string length is sufficient to handle boundary situations; 4. It is not recommended to use strrev() substr() combination method because it is not safe and inefficient for multi-byte characters.

How to set and get session variables in PHP? How to set and get session variables in PHP? Jul 12, 2025 am 03:10 AM

To set and get session variables in PHP, you must first always call session_start() at the top of the script to start the session. 1. When setting session variables, use $_SESSION hyperglobal array to assign values ??to specific keys, such as $_SESSION['username']='john_doe'; it can store strings, numbers, arrays and even objects, but avoid storing too much data to avoid affecting performance. 2. When obtaining session variables, you need to call session_start() first, and then access the $_SESSION array through the key, such as echo$_SESSION['username']; it is recommended to use isset() to check whether the variable exists to avoid errors

How to prevent SQL injection in PHP How to prevent SQL injection in PHP Jul 12, 2025 am 03:02 AM

Key methods to prevent SQL injection in PHP include: 1. Use preprocessing statements (such as PDO or MySQLi) to separate SQL code and data; 2. Turn off simulated preprocessing mode to ensure true preprocessing; 3. Filter and verify user input, such as using is_numeric() and filter_var(); 4. Avoid directly splicing SQL strings and use parameter binding instead; 5. Turn off error display in the production environment and record error logs. These measures comprehensively prevent the risk of SQL injection from mechanisms and details.

See all articles