青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

FireEmissary

  C++博客 :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
  14 隨筆 :: 0 文章 :: 20 評論 :: 0 Trackbacks

KMP 算法并非優(yōu)化

算法書和數(shù)據(jù)結(jié)構(gòu)書對KMP算法多有介紹,稱只需對字符串掃描一遍不需回溯云云.然而,它恐怕只應(yīng)該作為一種思想存在;用于實(shí)際的字符串查找并不理想.要費(fèi)勁心血實(shí)現(xiàn)和優(yōu)化它,才能在特定的字符串上略微超過(也可能略微遜過)std::search.

 

 

KMP算法的基本思想,是利用需要匹配字符串的自身信息來避免回溯.(這里討論的算法是以C/C++為編程語言,因此下標(biāo)索引以0開始) 

例如:字符串PAT=abcabcde,里面第二段的abcPAT開頭的字符是匹配的.

假如我們有個要查找的字符串TEXT=abcabD...,在比較到TEXT'D'(TEXT[5])也即到了PAT的第二個'c'(PAT[5])時比較失敗,一般的字符串查找又得從TEXT[1]('b')開始查找PAT.KMP算法知道PAT的第二段abc匹配自身的開頭字符串,它會對PAT存儲如下next:0 0 0 1 2 3 0 0數(shù)字代表匹配失敗后應(yīng)該從PAT的第多少個位置開始比較.我們這里在PAT[5]處失敗,而前面的PAT[0...4]都比較成功,因此先看看PAT[5]的上一個成功位置的next信息:next[4]=2,這代表應(yīng)該從PAT[2]處重新開始比較(即說明有2個字符不需要比了),就不需要跳到TEXT[1]處重新啟動查找,這時的PAT[0...1]為”ab,TEXT'D'的前面兩個也是”ab,只需要開始比較TEXT[5]PAT[2],KMP說的無回溯意義正是如此:不需要回溯TEXT的比較位置.如果PAT[2]又失敗了,next[1]=0.那么TEXT[5]PAT[0]開始比較,不成功的話TEXT遞增到TEXT[6],一直遞增到成功為止,成功的話當(dāng)然PAT也開始遞增.

偽碼如下:

 

template<class I>

I find(I beg,I end)

{

int patPos=0;

while (beg!=end)

{

if (*beg==PatChar[patPos])

{//匹配時遞增文本和模式的指針.

++beg;

if (++patPos!=sizePat)

continue;

//如果模式指針遞增了模式的長度那么多次,說明比較成功,返回指針

return beg-=failFunc.size(); 

}


else if (patPos)//根據(jù)next表信息調(diào)整模式串要比較的位置

patPos
=nextTable(--patPos);

else

++beg;

 

}


return end;

}


 

我用微軟的wingdi.h頭文件測試,方法是讀入后自加到1M以上,在里面找”IN HDC, IN UINT””PolyPolyline這樣的串若干次.

實(shí)測性能非常低,既比不過std::string::find,也比不過std::search.

 

于是我進(jìn)行了第一次優(yōu)化.像很多書本的作者正確指出的那樣,一般的程序員對該優(yōu)化的地方常常估計(jì)錯誤:

請看前面說的PAT[5]失敗的地方,它跳轉(zhuǎn)到PAT[2]開始比較,然而PAT[2]比較必定失敗,為什么?因?yàn)?span mce_style="font-family: 'Times New Roman';">PAT[5]==PAT[2]='c',PAT[5]失敗當(dāng)然PAT[2]也會失敗,我的優(yōu)化移除此類情況,也即next:0 0 0 1 2 3 0 0優(yōu)化后變?yōu)?span mce_style="font-family: 'Times New Roman';">:0 0 0 0 0 3 0 0 .

興沖沖的重新編譯運(yùn)行換來的卻是些微的提升.顯然這不是影響性能的地方.

 

分析良久后也沒找到應(yīng)該改進(jìn)的地方,因?yàn)?span mce_style="font-family: 'Times New Roman';">std::search的代碼比較平凡.最后抱著試試看的心理,把代碼替換了:

 

template<class I>

I find(I beg,I end)

{ …

beg
=std::find(beg,end, PatChar[0]);

int patPos=0;



else if (patPos)

patPos
=nextTable(--patPos);

else

{

beg
=std::find(beg,end, PatChar[0]);

patPos
=0;

}


}


return end;

}

帶來了巨大的速度提升,使得KMP查找的速度大大提升,gcc上比string.find,vs 2008std::search快了(,換句話說就是比gccstd::search,vs 2008string.find...)

 

,總算發(fā)現(xiàn)性能低下的真正原因了:在一大塊文本中找少量匹配的文本,最好是先濾掉不匹配的.對于不匹配的情況,std::find需要的指令更少;因此先用它來跳過不匹配的字符后在進(jìn)入KMP比較算法的核心會帶來可觀的速度提升.

 

那么接下來還有什么高級手段使得KMP算法大大改進(jìn)嗎?我嘗試了很久.然而很遺憾,沒有什么再值得慶祝的優(yōu)化了:它們增加了10倍的煩惱,換來一點(diǎn)點(diǎn)的性能提升.比方說:對于PAT=abcabcde,它的前置串”abcabnext值都為0,意味著可以先提前用簡單的代碼去比較”abcab,一旦比較失敗又繼續(xù)從失敗處開始找而不需要去查看next.因此我的實(shí)際代碼是用findFront_代替了std::find來干這事.這讓KMP算法提升了一點(diǎn)點(diǎn)性能,付出了n天思考和除錯的時間.

 

最終的成型算法是這樣的結(jié)果:gcc自帶的string::find要快,偶爾(通過對比較文本串的大小和比較次數(shù)調(diào)整)快于gccstd::search;vs 2008std::search,vs 2008string::find秒殺....

 

結(jié)論:

 1.簡單的代碼編譯器容易優(yōu)化.也適合現(xiàn)代處理器的預(yù)測執(zhí)行技術(shù)和cache.

2.日常用的要查找的字符串不會有多少適合KMP查找:abcabcabcabcnext表是什么值?優(yōu)化后應(yīng)該全為0!我對著wingdi.h看了幾遍才找到了像”WINGDIAPI BOOL WINAPI,PATPAINT這些歪瓜劣棗,它們的next表優(yōu)化后也只有一兩個地方有值.KMP算法應(yīng)該適用在文本中大量字符串重復(fù)且要找的子串也自身重復(fù)的情況.

3.去實(shí)現(xiàn)KMP查找不如用std::search.

 

代碼下載

 

花絮:

    gccstring::find很低效;因?yàn)樗鼈兙褪怯?span mce_style="font-family: 'Times New Roman';">char_trait的eq一個個去找,vs2008的是用memchr先找到一個再去比較整個串.也許unix世界習(xí)慣了用正則庫根本不怎么用標(biāo)準(zhǔn)庫自帶的.

  不過gccstring::find低效是相對自己的其它庫函數(shù)而言.它編譯的測試代碼普遍比vs2008的快上一倍以上.

   vs2008std::search比較低效;就是平凡地一個字符一個字符對比;gccstd::search先用std::find找到第一個相等的字符后再去比較整個串.(看這里和string::find情況反過來了)

   vs2008std::find很平凡,只是對char的情況特化成memchr;gccfind對隨機(jī)迭代器做了優(yōu)化,循環(huán)展開成44個地比較.

 

測試環(huán)境:xp sp3 

Cpu:amd 5000超頻到2.7G 

內(nèi)存:ddr2 2G.

posted on 2010-07-01 21:34 FireEmissary 閱讀(4036) 評論(2)  編輯 收藏 引用

評論

# re: KMP 算法并非字符串查找的優(yōu)化[未登錄] 2010-07-03 08:52 Lucifer
同意樓主的觀點(diǎn)。大體來說,

1.少量字符串,標(biāo)準(zhǔn)庫的執(zhí)行效率是最好的。
2.中等規(guī)模字符串,KMP 算法比較有優(yōu)勢。
3.大量字符串,BM 及其變種算法比較有優(yōu)勢。

這個是我對字符串精確匹配算法應(yīng)用的認(rèn)識。不對之處,還請指教。

PS: boost 庫中應(yīng)該有這些算法的實(shí)現(xiàn)吧。  回復(fù)  更多評論
  

# re: KMP 算法并非字符串查找的優(yōu)化 2010-07-06 15:10 djx_zh
glibc中用SSE4.2指令集優(yōu)化的KMP算法,號稱最快可以比c的strstr函數(shù)加速10倍。  回復(fù)  更多評論
  


只有注冊用戶登錄后才能發(fā)表評論。
網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            久久中文字幕一区二区三区| 久久精品视频99| 欧美日韩在线观看一区二区三区| 欧美一区二区三区精品| 亚洲综合清纯丝袜自拍| 午夜在线不卡| 久久婷婷av| 欧美日韩一区二区在线观看| 国产精品久久久久毛片大屁完整版| 欧美午夜电影在线| 国产深夜精品福利| 亚洲激情视频在线| 亚洲一区欧美二区| 久久影院午夜片一区| 亚洲第一在线综合在线| 亚洲欧洲精品一区二区| 久久激情视频| 久久婷婷国产综合国色天香| 欧美成年人在线观看| 亚洲日韩中文字幕在线播放| 一本色道久久99精品综合 | 一本大道久久精品懂色aⅴ| 亚洲天堂免费观看| 久久五月天婷婷| 亚洲日本在线观看| 亚洲在线免费观看| 欧美精品18videos性欧美| 国产欧美视频在线观看| 亚洲精品影视| 久久精品日产第一区二区三区| 亚洲国产欧美日韩精品| 欧美亚洲综合另类| 欧美特黄一级| 亚洲精品资源美女情侣酒店| 久久久97精品| 亚洲一区二区三区中文字幕| 欧美jizz19性欧美| 国产综合一区二区| 午夜精彩视频在线观看不卡| 亚洲激情电影在线| 久久久爽爽爽美女图片| 国产精品色网| 亚洲图片欧洲图片日韩av| 亚洲国产日本| 狠久久av成人天堂| 亚洲男女自偷自拍| 99精品欧美一区二区三区| 久久视频这里只有精品| 精品盗摄一区二区三区| 欧美一站二站| 在线亚洲自拍| 欧美日韩免费观看一区 | 欧美专区在线| 一本色道久久综合亚洲精品不| 免费日韩av电影| 黄色在线一区| 久久精品亚洲精品| 午夜国产精品视频免费体验区| 欧美日韩大片| 亚洲四色影视在线观看| 一本大道久久a久久精二百| 欧美日韩精品系列| 中文精品99久久国产香蕉| 亚洲精品免费在线播放| 欧美日韩精品不卡| 亚洲午夜电影在线观看| 一区二区三区四区蜜桃| 国产精品毛片a∨一区二区三区|国| 亚洲一区二区三区精品在线| 亚洲午夜羞羞片| 国产日韩欧美a| 久久综合色一综合色88| 乱人伦精品视频在线观看| 午夜精品一区二区三区四区| 一区二区三区高清在线| 欧美国产一区二区三区激情无套| 欧美一区二区女人| 国产视频精品va久久久久久| 欧美在线精品免播放器视频| 亚洲五月婷婷| 国产综合18久久久久久| 免费在线成人av| 久久久久国产精品麻豆ai换脸| 激情伊人五月天久久综合| 美女主播精品视频一二三四| 裸体女人亚洲精品一区| 亚洲美女啪啪| 亚洲欧美999| 亚洲国产精品www| 一本到高清视频免费精品| 国产一区二区三区精品久久久| 免费亚洲电影在线| 欧美日韩亚洲高清一区二区| 性欧美18~19sex高清播放| 久久av一区二区三区亚洲| 亚洲精品久久久久久久久| 亚洲一区二区成人| 亚洲欧洲精品成人久久奇米网| 在线亚洲精品| 91久久精品国产91久久| 亚洲男人的天堂在线aⅴ视频| 亚洲电影在线看| 亚洲一级在线| 亚洲人成网站精品片在线观看 | 亚洲午夜精品一区二区三区他趣 | 亚洲福利视频二区| 欧美日韩亚洲不卡| 免费欧美在线视频| 国产精品香蕉在线观看| 亚洲精品乱码| 亚洲国产老妈| 新片速递亚洲合集欧美合集| 亚洲美女诱惑| 老司机成人网| 久久久综合视频| 国产精品一区二区三区免费观看 | 久久精品国产在热久久| 欧美经典一区二区| 欧美v亚洲v综合ⅴ国产v| 国产日韩欧美精品在线| 在线一区免费观看| 亚洲午夜影视影院在线观看| 蜜月aⅴ免费一区二区三区| 久久久久久久97| 欧美va亚洲va香蕉在线| 亚洲男人第一网站| 亚洲一区二区伦理| 欧美国产极速在线| 欧美激情第一页xxx| 狠狠色狠色综合曰曰| 欧美一区二区精品| 午夜精品一区二区三区四区| 国产精品成人免费精品自在线观看| 亚洲经典三级| 在线视频亚洲| 欧美美女视频| 99国产成+人+综合+亚洲欧美| 一级成人国产| 欧美日韩在线亚洲一区蜜芽| 亚洲精品国产无天堂网2021| 亚洲理论在线观看| 欧美日本久久| 制服丝袜激情欧洲亚洲| 欧美一级久久久久久久大片| 国产九九精品视频| 性亚洲最疯狂xxxx高清| 久久中文字幕一区| 亚洲国产一区视频| 欧美成人69av| 一本久道久久综合狠狠爱| 一区二区三区国产精品| 欧美精品一区二区三区一线天视频 | 亚洲欧美国产精品桃花| 久久国产天堂福利天堂| 国产喷白浆一区二区三区| 午夜精品久久久久久久| 久久一区二区三区超碰国产精品 | 亚洲一区二区三区中文字幕在线| 国产精品超碰97尤物18| 亚洲欧美一区二区三区极速播放| 久久精品国产第一区二区三区最新章节| 国产精品一区三区| 久久精品人人做人人爽| 欧美www视频在线观看| 中文亚洲视频在线| 国产亚洲一区精品| 欧美人妖在线观看| 亚洲欧美日韩国产一区二区三区| 久久综合国产精品台湾中文娱乐网| 亚洲高清一二三区| 国产精品www| 久久久精品性| 日韩亚洲国产欧美| 久久午夜电影网| 亚洲一区三区在线观看| 精品成人国产在线观看男人呻吟| 欧美大香线蕉线伊人久久国产精品| 一区二区三区波多野结衣在线观看| 欧美中文字幕久久| 日韩一级精品视频在线观看| 国产精品婷婷| 欧美日本高清视频| 久久夜色精品国产| 午夜精品999| 亚洲日本成人网| 久久视频这里只有精品| 亚洲欧美日韩精品综合在线观看| 在线日韩中文字幕| 国产精品网站在线播放| 一区二区三区精品久久久| 激情成人综合网| 欧美日韩精品一区二区在线播放| 久久丁香综合五月国产三级网站| 亚洲欧洲在线视频| 久久综合一区| 久久精品五月婷婷| 亚洲欧美另类久久久精品2019| 亚洲第一精品久久忘忧草社区| 国产精品福利网站| 欧美日本亚洲韩国国产|