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

那誰的技術(shù)博客

感興趣領(lǐng)域:高性能服務(wù)器編程,存儲,算法,Linux內(nèi)核
隨筆 - 210, 文章 - 0, 評論 - 1183, 引用 - 0
數(shù)據(jù)加載中……

KMP算法的實現(xiàn)

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

//?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數(shù)組
????GetNextArray(T,?next);

????
int?i,?j;
????
for?(i?=?pos,?j?=?0;?i?<?S->length?&&?j?<?T->length;?)
????
{
????????
//?i是主串游標,j是模式串游標
????????if?(-1?==?j?||????????????????//?模式串游標已經(jīng)回退到第一個位置
????????????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數(shù)組.
這是一個遞推求解的過程,初始的情況是next[0] = -1.
假設(shè)在某一個時刻有如下的等式成立:str[0...k-1] = str[j - k...j - 1],那么next[j] = k,在這個前提下,繼續(xù)進行下一個字符的匹配.
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數(shù)組的算法如下:

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

????
// ?第一個字符的next值是-1,因為C中的數(shù)組是從0開始的
????next[ 0 ]? = ? - 1 ;
????
for ?( int ?i? = ? 0 ,?j? = ? - 1 ;?i? < ?pstr -> length? - ? 1 ;?)
????
{
????????
// ?i是主串的游標,j是模式串的游標
????????
// ?這里的主串和模式串都是同一個字符串
???????? if ?( - 1 ? == ?j? || ???????????????????????? // ?如果模式串游標已經(jīng)回退到第一個字符
????????????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:????????李創(chuàng)
????????????????
http://m.shnenglu.com/converse/
????????????????
????????????????參考資料:?嚴蔚敏<<數(shù)據(jù)結(jié)構(gòu)>>

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


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

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

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

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

????
// ?第一個字符的next值是-1,因為C中的數(shù)組是從0開始的
????next[ 0 ]? = ? - 1 ;
????
for ?( int ?i? = ? 0 ,?j? = ? - 1 ;?i? < ?pstr -> length? - ? 1 ;?)
????
{
????????
// ?i是主串的游標,j是模式串的游標
????????
// ?這里的主串和模式串都是同一個字符串
???????? if ?( - 1 ? == ?j? || ???????????????????????? // ?如果模式串游標已經(jīng)回退到第一個字符
????????????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數(shù)組
????GetNextArray(T,?next);

????
int ?i,?j;
????
for ?(i? = ?pos,?j? = ? 0 ;?i? < ?S -> length? && ?j? < ?T -> length;?)
????
{
????????
// ?i是主串游標,j是模式串游標
???????? if ?( - 1 ? == ?j? || ???????????????? // ?模式串游標已經(jīng)回退到第一個位置
????????????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 那誰 閱讀(7388) 評論(8)  編輯 收藏 引用 所屬分類: 算法與數(shù)據(jù)結(jié)構(gòu)

評論

# re: KMP算法的實現(xiàn)  回復(fù)  更多評論   

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

# re: KMP算法的實現(xiàn)  回復(fù)  更多評論   

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

# re: KMP算法的實現(xiàn)  回復(fù)  更多評論   

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

# re: KMP算法的實現(xiàn)  回復(fù)  更多評論   

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

# re: KMP算法的實現(xiàn)  回復(fù)  更多評論   

2011-10-07 19:16 | kol

# re: KMP算法的實現(xiàn)  回復(fù)  更多評論   

這個應(yīng)該有簡單的算法吧 ~~ 不用這么多的函數(shù) ~~
2011-10-07 19:25 | kol

# re: KMP算法的實現(xiàn)  回復(fù)  更多評論   

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

# re: KMP算法的實現(xiàn)  回復(fù)  更多評論   

哦,不好意思,看錯了
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>
            欧美激情一区二区| 亚洲尤物精选| 亚洲大片在线观看| 一区二区三区国产在线| 一区二区三区黄色| 亚洲欧洲日产国产综合网| 一区二区三区四区五区在线| 亚洲制服av| 亚洲天堂免费在线观看视频| 久久免费视频在线| 欧美二区在线观看| 久久野战av| 欧美一区2区三区4区公司二百| 久久青草久久| 亚洲国产日韩在线| 最新亚洲激情| 欧美福利视频网站| 欧美在线日韩在线| 狠狠色综合色区| 久久精品中文字幕一区二区三区| 亚洲一区国产| 欧美日韩一区二区三区在线看 | 亚洲第一福利视频| 久久精品一级爱片| 久久婷婷av| 国产在线欧美| 欧美在线你懂的| 久久综合精品一区| 亚洲午夜精品久久| 亚洲欧美日韩国产成人精品影院| 国产麻豆综合| 亚洲精品欧美在线| 国产精品另类一区| 日韩亚洲一区二区| 香蕉国产精品偷在线观看不卡| 1000部精品久久久久久久久| 夜夜嗨av色综合久久久综合网| 国产一区二区三区精品欧美日韩一区二区三区 | 久久久精品一品道一区| 久久aⅴ国产欧美74aaa| 亚洲欧洲久久| 欧美一区二区三区久久精品| 91久久视频| 欧美中文在线视频| 亚洲一区二区三| 欧美国产日韩精品免费观看| 久久久久久久综合色一本| 欧美日韩视频在线第一区| 欧美成人有码| 在线播放亚洲一区| 久久精品视频在线| 一区二区三区视频观看| 欧美日韩国产大片| 一区二区av在线| 亚洲一区二区三区影院| 狂野欧美一区| 乱码第一页成人| 在线国产精品播放| 美女图片一区二区| 亚洲三级观看| 亚洲国产高清一区二区三区| 蜜桃视频一区| 99精品欧美一区二区三区 | 免费成人在线观看视频| 久久日韩精品| 亚洲黄色av一区| 欧美日韩精品一区二区| 99国内精品久久| 99精品国产在热久久婷婷| 亚洲欧美日韩精品在线| 欧美日韩精品免费观看视频| 日韩视频不卡中文| 久久综合久久综合久久| 美女久久一区| 亚洲永久免费| 亚洲国产综合视频在线观看| 欧美另类亚洲| 久久精品国产综合精品| 99视频精品在线| 久久夜色撩人精品| 亚洲欧美日韩国产综合| 1000部精品久久久久久久久| 欧美日韩另类一区| 久久国内精品视频| 亚洲一区二区三区国产| 久久国产乱子精品免费女| 亚洲每日在线| 在线观看视频日韩| 国产一区二区三区四区老人| 欧美不卡视频一区发布| 噜噜噜噜噜久久久久久91| 久久夜色精品亚洲噜噜国产mv| 久久天堂成人| 欧美日产在线观看| 国产免费观看久久| 亚洲国产婷婷香蕉久久久久久| 日韩小视频在线观看| 亚洲制服av| 久久久久久久久蜜桃| 久久国产综合精品| 欧美福利视频| 亚洲在线不卡| 欧美极品一区| 黑人操亚洲美女惩罚| 亚洲国产精品v| 亚洲女女女同性video| 免费观看一区| 欧美福利专区| 久久综合国产精品| 日韩一二三区视频| 女人香蕉久久**毛片精品| 国产一区二区在线观看免费| 欧美成人在线免费观看| 国产日产欧美a一级在线| 亚洲精品在线观| 免费在线日韩av| 欧美有码在线视频| 国产精品大片wwwwww| 亚洲精品一线二线三线无人区| 久久久久久伊人| 亚洲欧美在线磁力| 国产欧美一区二区三区沐欲 | 亚洲永久免费| 国产亚洲a∨片在线观看| 亚洲男女毛片无遮挡| 99精品视频网| 国产精品乱码久久久久久| 亚洲一区二区四区| 宅男噜噜噜66国产日韩在线观看| 欧美激情日韩| 亚洲视频一二区| 亚洲视频专区在线| 国产日本亚洲高清| 久热综合在线亚洲精品| 久久久综合免费视频| 亚洲精品久久久久久久久久久| 亚洲国产欧美久久| 欧美日韩国产页| 欧美在线二区| 免费日韩av电影| 亚洲影院免费观看| 亚洲一区三区在线观看| 亚洲成色www8888| 99视频精品在线| 亚洲电影欧美电影有声小说| 亚洲韩国一区二区三区| 国产精品一区二区久激情瑜伽| 欧美视频手机在线| 蜜臀久久99精品久久久久久9 | 欧美成人午夜激情在线| 亚洲欧美怡红院| 欧美精品高清视频| 牛牛精品成人免费视频| 国产欧美日韩高清| 亚洲区一区二| 红杏aⅴ成人免费视频| 亚洲午夜av在线| 99精品热视频| 女主播福利一区| 久久亚洲捆绑美女| 国产精品一区二区三区四区五区| 亚洲成人自拍视频| 欧美黄色一区| 久久久国产视频91| 国内精品福利| 久久xxxx| 蜜桃视频一区| 在线精品视频一区二区三四| 欧美亚洲一区二区三区| 久久av一区二区三区亚洲| 国产精品免费视频观看| 一区二区毛片| 亚洲男人第一网站| 国产丝袜一区二区| 久久亚洲春色中文字幕| 欧美成人国产| 国内在线观看一区二区三区| 久久狠狠一本精品综合网| 久久9热精品视频| 亚洲第一网站免费视频| 麻豆国产精品va在线观看不卡| 欧美激情第二页| 亚洲尤物视频在线| 国产一区清纯| 欧美性一区二区| 久久久久久久久久看片| 亚洲精品老司机| 美女视频黄a大片欧美| 日韩视频一区| 国模套图日韩精品一区二区| 欧美激情免费观看| 久久久久久夜精品精品免费| 亚洲精品久久久久久久久久久久| 欧美精品久久99| 这里只有精品丝袜| 免费精品99久久国产综合精品| 亚洲一卡久久| 亚洲性视频网址| 亚洲精品在线视频| 亚洲黄色在线观看|