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

那誰的技術博客

感興趣領域:高性能服務器編程,存儲,算法,Linux內核
隨筆 - 210, 文章 - 0, 評論 - 1183, 引用 - 0
數據加載中……

KMP算法的實現

KMP算法是一種用于字符串匹配的算法,這個算法的高效之處在于當在某個位置匹配不成功的時候可以根據之前的匹配結果從模式字符串的另一個位置開始,而不必從頭開始匹配字符串.
因此這個算法的關鍵在于,當某個位置的匹配不成功的時候,應該從模式字符串的哪一個位置開始新的比較.假設這個值存放在一個next數組中,其中next數組中的元素滿足這個條件:next[j] = k,表示的是當模式字符串中的第j + 1個(這里是遵守標準C語言中數組元素從0開始的約定,以下不再說明)發生匹配不成功的情況時,應該從模式字符串的第k + 1個字符開始新的匹配.如果已經得到了模式字符串的next數組,那么KMP算法的實現如下:

//?KMP字符串模式匹配算法
//?輸入:?S是主串,T是模式串,pos是S中的起始位置
//?輸出:?如果匹配成功返回起始位置,否則返回-1
int?KMP(PString?S,?PString?T,?int?pos)
{
????assert(NULL?
!=?S);
????assert(NULL?
!=?T);
????assert(pos?
>=?0);
????assert(pos?
<?S->length);
????
????
if?(S->length?<?T->length)
????????
return?-1;

????printf(
"主串\t?=?%s\n",?S->str);
????printf(
"模式串\t?=?%s\n",?T->str);

????
int?*next?=?(int?*)malloc(T->length?*?sizeof(int));
????
//?得到模式串的next數組
????GetNextArray(T,?next);

????
int?i,?j;
????
for?(i?=?pos,?j?=?0;?i?<?S->length?&&?j?<?T->length;?)
????
{
????????
//?i是主串游標,j是模式串游標
????????if?(-1?==?j?||????????????????//?模式串游標已經回退到第一個位置
????????????S->str[i]?==?T->str[j])?//?當前字符匹配成功
????????{
????????????
//?滿足以上兩種情況時兩個游標都要向前進一步
????????????++i;
????????????
++j;
????????}

????????
else????????????????????????//??匹配不成功,模式串游標回退到當前字符的next值
????????{
????????????j?
=?next[j];
????????}

????}


????free(next);

????
if?(j?>=?T->length)
????
{
????????
//?匹配成功
????????return?i?-?T->length;
????}

????
else
????
{
????????
//?匹配不成功
????????return?-1;
????}

}


下面看看如何得到next數組.
這是一個遞推求解的過程,初始的情況是next[0] = -1.
假設在某一個時刻有如下的等式成立:str[0...k-1] = str[j - k...j - 1],那么next[j] = k,在這個前提下,繼續進行下一個字符的匹配.
1)如果str[0...k] = str[j - k...j],那么next[j + 1] = next[j] + 1 = k + 1.
2)反之,如果上面的匹配不成立,那么就要從next[k]開始進行新的匹配,如果成功的話,那么:
next[j + 1] = next[next[j]] + 1 = next[k] + 1;
如果還是不能匹配成功就再從next[next[k]]的位置開始進行的新的匹配,直到匹配成功為止.如果這個過程一直進行下去都沒有找到可以成功匹配的字符的話,那么next[j + 1] = 0,這時表示要從字符串的第一個位置開始新的匹配了.
用一個公式表示上述的算法,那么可以寫作:
next[j] =
1)-1,當j = 0時;
2) Max{k | 0 <= k < j && str[0..k - 1] = str[j - k...j - 1]};
3)0,其他情況,此時匹配要從第一個位置重新開始.
尋找next數組的算法如下:

// ?得到字符串的next數組
void ?GetNextArray(PString?pstr,? int ?next[])
{
????assert(NULL?
!= ?pstr);?
????assert(NULL?
!= ?next);
????assert(pstr
-> length? > ? 0 );

????
// ?第一個字符的next值是-1,因為C中的數組是從0開始的
????next[ 0 ]? = ? - 1 ;
????
for ?( int ?i? = ? 0 ,?j? = ? - 1 ;?i? < ?pstr -> length? - ? 1 ;?)
????
{
????????
// ?i是主串的游標,j是模式串的游標
????????
// ?這里的主串和模式串都是同一個字符串
???????? if ?( - 1 ? == ?j? || ???????????????????????? // ?如果模式串游標已經回退到第一個字符
????????????pstr -> str[i]? == ?pstr -> str[j])???? // ?如果匹配成功
???????? {
????????????
// ?兩個游標都向前走一步
???????????? ++ i;
????????????
++ j;
????????????
// ?存放當前的next值為此時模式串的游標值
????????????next[i]? = ?j;
????????}

????????
else ???????????????????????????????? // ?匹配不成功j就回退到上一個next值
???????? {
????????????j?
= ?next[j];
????????}

????}

}



完整的算法如下:
/* *******************************************************************
????created:????2006/07/02
????filename:?????KMP.cpp
????author:????????李創
????????????????
http://www.shnenglu.com/converse/
????????????????
????????????????參考資料:?嚴蔚敏<<數據結構>>

????purpose:????KMP字符串匹配算法的演示
********************************************************************
*/


#include?
< stdio.h >
#include?
< stdlib.h >
#include?
< assert.h >
#include?
< string .h >

#define ?MAX_LEN_OF_STR????30???????????? // ?字符串的最大長度

typedef?
struct ?String???????????????? // ?這里需要的字符串數組,存放字符串及其長度
{
????
char ????str[MAX_LEN_OF_STR];???? // ?字符數組
???? int ????????length;???????????????????? // ?字符串的實際長度
}
String,? * PString;

// ?得到字符串的next數組
void ?GetNextArray(PString?pstr,? int ?next[])
{
????assert(NULL?
!= ?pstr);?
????assert(NULL?
!= ?next);
????assert(pstr
-> length? > ? 0 );

????
// ?第一個字符的next值是-1,因為C中的數組是從0開始的
????next[ 0 ]? = ? - 1 ;
????
for ?( int ?i? = ? 0 ,?j? = ? - 1 ;?i? < ?pstr -> length? - ? 1 ;?)
????
{
????????
// ?i是主串的游標,j是模式串的游標
????????
// ?這里的主串和模式串都是同一個字符串
???????? if ?( - 1 ? == ?j? || ???????????????????????? // ?如果模式串游標已經回退到第一個字符
????????????pstr -> str[i]? == ?pstr -> str[j])???? // ?如果匹配成功
???????? {
????????????
// ?兩個游標都向前走一步
???????????? ++ i;
????????????
++ j;
????????????
// ?存放當前的next值為此時模式串的游標值
????????????next[i]? = ?j;
????????}

????????
else ???????????????????????????????? // ?匹配不成功j就回退到上一個next值
???????? {
????????????j?
= ?next[j];
????????}

????}

}


// ?KMP字符串模式匹配算法
// ?輸入:?S是主串,T是模式串,pos是S中的起始位置
// ?輸出:?如果匹配成功返回起始位置,否則返回-1
int ?KMP(PString?S,?PString?T,? int ?pos)
{
????assert(NULL?
!= ?S);
????assert(NULL?
!= ?T);
????assert(pos?
>= ? 0 );
????assert(pos?
< ?S -> length);
????
????
if ?(S -> length? < ?T -> length)
????????
return ? - 1 ;

????printf(
" 主串\t?=?%s\n " ,?S -> str);
????printf(
" 模式串\t?=?%s\n " ,?T -> str);

????
int ? * next? = ?( int ? * )malloc(T -> length? * ? sizeof ( int ));
????
// ?得到模式串的next數組
????GetNextArray(T,?next);

????
int ?i,?j;
????
for ?(i? = ?pos,?j? = ? 0 ;?i? < ?S -> length? && ?j? < ?T -> length;?)
????
{
????????
// ?i是主串游標,j是模式串游標
???????? if ?( - 1 ? == ?j? || ???????????????? // ?模式串游標已經回退到第一個位置
????????????S -> str[i]? == ?T -> str[j])? // ?當前字符匹配成功
???????? {
????????????
// ?滿足以上兩種情況時兩個游標都要向前進一步
???????????? ++ i;
????????????
++ j;
????????}

????????
else ???????????????????????? // ??匹配不成功,模式串游標回退到當前字符的next值
???????? {
????????????j?
= ?next[j];
????????}

????}


????free(next);

????
if ?(j? >= ?T -> length)
????
{
????????
// ?匹配成功
???????? return ?i? - ?T -> length;
????}

????
else
????
{
????????
// ?匹配不成功
???????? return ? - 1 ;
????}

}

posted on 2006-07-05 17:44 那誰 閱讀(7390) 評論(8)  編輯 收藏 引用 所屬分類: 算法與數據結構

評論

# re: KMP算法的實現  回復  更多評論   

數據結構課程上給過的算法.
說實話,我一直不能從書上那簡單的描述中理解這個算法,直到現在仍然如此,慚愧.
2006-07-05 18:13 | LOGOS

# re: KMP算法的實現  回復  更多評論   

沒關系,我也是花了好長時間才整明白的,自己實現一下估計就能清楚好多了~~
2006-07-05 18:18 | 創系

# re: KMP算法的實現  回復  更多評論   

求next函數其實就是自己和自己比一次。。kmp最重要就是求next函數了。。畫畫圖模擬一下,應該比較容易理解的:)
2006-07-08 12:18 |

# re: KMP算法的實現  回復  更多評論   

收藏
2006-12-08 15:12 | todaygood

# re: KMP算法的實現  回復  更多評論   

2011-10-07 19:16 | kol

# re: KMP算法的實現  回復  更多評論   

這個應該有簡單的算法吧 ~~ 不用這么多的函數 ~~
2011-10-07 19:25 | kol

# re: KMP算法的實現  回復  更多評論   

算法貌似錯了
計算
bacbabababacaca
ababaca 的時候
前綴是
-1 0 -1 0 -1 3 -1
結果 next[-1] 越界了
2012-04-26 12:01 | Davis

# re: KMP算法的實現  回復  更多評論   

哦,不好意思,看錯了
2012-04-26 12:11 | Davis
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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一区二区三区| 亚洲尤物在线视频观看| 亚洲国产高清一区| 久久久噜噜噜久久狠狠50岁| 国产欧美日韩免费看aⅴ视频| 妖精视频成人观看www| 欧美国产日韩视频| 久久国产色av| 国产精品露脸自拍| 亚洲一级在线观看| 亚洲精品一区二区三区在线观看| 美女黄毛**国产精品啪啪 | 欧美69wwwcom| 1024成人| 美腿丝袜亚洲色图| 狠狠色香婷婷久久亚洲精品| 欧美日韩一区三区| 国产亚洲成av人在线观看导航 | 麻豆成人综合网| 亚洲一级黄色片| 欧美日韩精品久久久| 亚洲精品一区二区三区99| 欧美xxx成人| 亚洲一区二区三区欧美| 欧美成人dvd在线视频| 国产伦精品一区二区三区四区免费 | 欧美成人午夜视频| 激情综合色综合久久| 久久国产视频网站| 亚洲婷婷综合色高清在线| 免费亚洲视频| 国产麻豆精品视频| 小黄鸭精品密入口导航| 一本色道久久88精品综合| 久久尤物视频| 伊人狠狠色j香婷婷综合| 欧美制服丝袜第一页| 亚洲视频一区在线| 国产精品丝袜91| 亚洲摸下面视频| 中文亚洲视频在线| 国产精品a久久久久| 亚洲一区影院| 欧美三日本三级三级在线播放| 亚洲美女av网站| 亚洲激情影院| 欧美va亚洲va国产综合| 国产揄拍国内精品对白| 玖玖综合伊人| 久久综合色婷婷| 国产综合网站| 免费观看在线综合| 久久先锋影音av| 亚洲人成人一区二区三区| 欧美激情日韩| 欧美日韩另类综合| 亚洲尤物在线视频观看| 欧美亚洲日本国产| 精品999成人| 亚洲国产欧美日韩另类综合| 欧美伦理a级免费电影| 亚洲天堂av综合网| 亚洲免费视频观看| 在线观看亚洲视频| 亚洲国产欧美日韩| 国产精品美女主播| 久久久久网址| 欧美粗暴jizz性欧美20| 一区二区三区久久| 夜夜嗨av色一区二区不卡| 国产欧美综合一区二区三区| 欧美一区二区三区视频| 久久精品视频在线观看| 亚洲国产小视频在线观看| 99精品久久| 国产精品丝袜91| 欧美激情视频在线免费观看 欧美视频免费一| 免费在线看一区| 午夜一区不卡| 久久久久国产精品厨房| 99国产精品| 亚洲欧美日韩第一区| 在线免费观看成人网| 亚洲精品在线电影| 国产一区二区三区在线观看免费| 欧美国产日韩精品| 国产精品一卡二| 欧美国产1区2区| 欧美午夜精品久久久久久久| 欧美一区二区视频网站| 久久久久国产精品一区二区| 亚洲精品影院| 一本到高清视频免费精品| 国产一区二区三区免费观看| 欧美激情一区在线观看| 国产精品久久久久久av下载红粉 | 亚洲激情小视频| 一区二区三区视频在线| 伊人狠狠色j香婷婷综合| 一区二区三区国产在线观看| 国内揄拍国内精品久久| 99视频一区二区三区| 狠狠干成人综合网| 一本一本久久a久久精品综合麻豆 一本一本久久a久久精品牛牛影视 | 午夜影院日韩| 亚洲人午夜精品免费| 久久国产夜色精品鲁鲁99| 日韩一级在线观看| 久久久久**毛片大全| 亚洲影院一区| 免费一级欧美片在线观看| 欧美在线不卡视频| 欧美阿v一级看视频| 亚洲欧美日韩一区在线观看| 免费成人av资源网| 香蕉成人啪国产精品视频综合网| 午夜精品久久久久久久99樱桃| 亚洲精品视频在线看| 欧美在线亚洲| 9l视频自拍蝌蚪9l视频成人| 欧美亚洲尤物久久| 99综合在线| 免费久久99精品国产自在现线| 性欧美1819性猛交| 欧美激情一区二区三区在线视频| 久久亚洲综合网| 欧美日韩美女| 亚洲动漫精品| 国产精品视频不卡| 99在线精品观看| 国产精品久久久久毛片软件| 亚洲精品四区| 亚洲国产精品成人va在线观看| 久久www成人_看片免费不卡| 亚洲综合日韩在线| 国产精品白丝av嫩草影院| 欧美激情bt| 亚洲黄色大片| 久久久久久久999精品视频| 久久精品论坛| 国产伦精品一区二区三区免费迷| 一本色道久久综合亚洲精品不卡 | 国产亚洲精品成人av久久ww| 亚洲精品在线观看视频| 亚洲精品中文字| 久久午夜国产精品| 免费成人性网站| 国产亚洲欧美在线| 久久精品视频一| 欧美国产先锋| 欧美一区二区三区在| 国产精品99免费看| 亚洲一级二级| 午夜国产精品视频免费体验区| 国产精品久久久久久久久久久久| 亚洲精品日韩欧美| 亚洲午夜一区| 欧美日韩久久久久久| 一区二区电影免费观看| 中文国产成人精品久久一| 欧美性开放视频| 一区二区三区高清| 久久9热精品视频| 国产乱人伦精品一区二区| 午夜在线不卡| 久久国产精品毛片| 黄色成人av网| 久久精品一区二区三区不卡牛牛| 免费欧美高清视频| 亚洲福利视频在线| 欧美噜噜久久久xxx| 亚洲人成网站在线播| 亚洲视频一区二区免费在线观看| 欧美日韩日日骚| 亚洲一区影音先锋| 欧美亚洲一区二区在线| 国产欧美亚洲日本| 香蕉久久久久久久av网站| 麻豆av一区二区三区久久| 亚洲第一级黄色片| 欧美日韩1234| 亚洲一区观看| 久久久一二三| 亚洲精品视频中文字幕| 欧美视频专区一二在线观看| 午夜伦欧美伦电影理论片| 久久综合九色综合欧美就去吻| 亚洲激情国产精品| 欧美韩日高清| 亚洲欧美一级二级三级| 久久综合九九| 一区二区三区国产盗摄|