C/C++中提高查找速度的小技巧
前言
當(dāng)看到題目是在一個(gè)數(shù)組中查找某一個(gè)元素,或是在一個(gè)字符串中查找某個(gè)字符,我們一般都會(huì)寫出如下代碼。但這樣的代碼雖然簡(jiǎn)潔明了,但在數(shù)組元素很多的情況下,并不是一個(gè)很好的解決方案,今天我就來(lái)分享一個(gè)提高查找速度的小技巧.
//在一個(gè)int數(shù)組中查找某個(gè)元素 int find(int A[],int n,int element) { for( int i = 0; i < n; i++ ) { if( A[i] == element ) return i; } return -1; } //在一個(gè)字符串中查找某個(gè)字符 int find(string& str,char c) { for( int i = 0; i < str.length(); i++ ) { if( str[i] == c ) return i; } return -1; }
雖然每次都是寫出這樣的代碼,但我總覺(jué)得for循環(huán)中的<判斷有點(diǎn)多余,比如數(shù)組中有100個(gè)元素,我們明明知道前99個(gè)是不會(huì)數(shù)組越界的,根本不需要判斷i<n的,但我們卻多判斷了99次,昨天晚上看編程珠璣的時(shí)候發(fā)現(xiàn)了這個(gè)小技巧,今天就來(lái)分享一下。
通過(guò)哨兵的方式去掉這多余的判斷,將上面兩個(gè)方法改造如下:
//在一個(gè)int數(shù)組中查找某個(gè)元素 int find1(int A[],int n,int element) { if( n <= 0 ) return -1; if( A[--n] == element ) return n; int hold = A[n]; A[n] = element; int i = 0; for( ; ; i++ ) { if( A[i] == element ) break; } A[n] = hold; return i < n ? i : -1; } //在一個(gè)字符串中查找某個(gè)字符 int find1(string& str,char c) { int n = str.length(); if( n <= 0 ) return -1; if( str[--n] == c ) return n; int hold = str[n]; str[n] = c; int i = 0; for( ; ; i++ ) { if( str[i] == c ) break; } str[n] = hold; return i < n ? i : -1; }
我勒個(gè)去,怎么變得這么長(zhǎng),但的確是減少了判斷的次數(shù),如果數(shù)組較大的話提高運(yùn)行速度肯定是一定的,如果你非要說(shuō)數(shù)組很小的話,說(shuō)不定速度還要降低呢,那你不這樣寫不就得了,好了廢話少說(shuō),雖然代碼已經(jīng)很簡(jiǎn)單明了了,但我還是簡(jiǎn)單說(shuō)一下思路。
就是在數(shù)組的末尾加一個(gè)哨兵,即使不判斷i<n也能確保數(shù)組不越界,加了哨兵之后if語(yǔ)句是必然會(huì)break的。
先判斷最后一個(gè)元素的值是不是我們要查找的數(shù),如果是,返回其下標(biāo);如果不是,將最后一個(gè)數(shù)的值保存起來(lái),將要查找的那個(gè)數(shù)賦給最后一個(gè)元素,循環(huán)查找指定的元素,不用判斷數(shù)組越界,if語(yǔ)句必然break,將最后一個(gè)元素的值還原,最后只用判斷i<n,如果是i即為所求,否則要查找的元素不在數(shù)組中。
最后在做一個(gè)簡(jiǎn)單的性能測(cè)試,看到底能否提高查找速度。
測(cè)試代碼如下:
void testFind() { int N = 200000; int* A = new int[N]; A[N-2] = 1; DWORD start = ::GetTickCount64(); for( int i = 0; i < 10000; i++ ) find(A,N,1); DWORD end = ::GetTickCount64(); cout <<"優(yōu)化前:" << end - start <<" 毫秒" << endl; start = ::GetTickCount64(); for( int i = 0; i < 10000; i++ ) find1(A,N,1); end = ::GetTickCount64(); cout <<"優(yōu)化后:" << end - start <<" 毫秒" << endl; }
運(yùn)行結(jié)果如下:
速度還是會(huì)快一點(diǎn)
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來(lái)一定的幫助,如果有疑問(wèn)大家可以留言交流。
相關(guān)文章
c++動(dòng)態(tài)庫(kù)調(diào)用的實(shí)現(xiàn)
本文主要介紹了c++動(dòng)態(tài)庫(kù)調(diào)用的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07C++中malloc與free、new與delete的詳解與應(yīng)用
今天小編就為大家分享一篇關(guān)于C++中malloc與free、new與delete的詳解與應(yīng)用,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2018-12-12c語(yǔ)言中位字段與結(jié)構(gòu)聯(lián)合的組合使用詳解
本篇文章是對(duì)c語(yǔ)言中位字段與結(jié)構(gòu)聯(lián)合的組合使用進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05C 語(yǔ)言基礎(chǔ)教程(我的C之旅開(kāi)始了)[七]
C 語(yǔ)言基礎(chǔ)教程(我的C之旅開(kāi)始了)[七]...2007-02-02C語(yǔ)言棧順序結(jié)構(gòu)實(shí)現(xiàn)代碼
一個(gè)能夠自動(dòng)擴(kuò)容的順序結(jié)構(gòu)的棧 ArrStack 實(shí)例 (GCC編譯),有需要的朋友可以參考一下2013-10-10用C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單五子棋小游戲
這篇文章主要為大家詳細(xì)介紹了用C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單五子棋小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-07-07