日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

KMP 算法——C

發布時間:2024/8/23 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 KMP 算法——C 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

? ? 昨天看了一下用于字符子串查找的KMP算法,很巧妙,也很難編,程序不長,理解起來可真是費勁。因為要用C語言來實現,所以書里KMP算法定義的next數組的求值方法需要改動,因為C語言里的字符串數據結構并不是讓第一位存儲字符串長度,而是直接保存了第一個字符,就是這樣一個小小的變化,可讓我傷透了腦筋,而且即便如此,對于算法的本質也不算了解得很透徹,幾乎是在死命調試的情況下把程序給實現出來,里面是不是有bug也不敢確定,編程可真是件糾結的事,要是早些接觸就好了,可以靜靜的思考,不用背負著找工作的壓力來學習。

? ? 尋找字符串的子串,結果返回第一個匹配的子串首字符的位置,從0開始。

1.先從簡單算法開始,簡單算法主要是通過循環來實現。

? ? int Index( char* s, char* t, int pos ) ? ? ? ?/*s為目標字符串,t為要尋找的字串,pos為s中的開始位置*/

? ? {

? ? ? ? int slen, tlen;

? ? ? ? int i = pos, j = 0; ? ? ? ?/*使用i標記s中的位置,使用j標記t中的位置*/

? ? ? ??if( s == NULL || t == NULL )

? ? ? ? ? ? return -1;

? ? ? ? slen = strlen( s );

? ? ? ? tlen = strlen( t );

? ? ? ? if( tlen > slen || pos < 0 || pos > tlen - 1 )

? ? ? ? ? ? return -1;

? ? ? ? while( i < slen && j < tlen )

? ? ? ? {

? ? ? ? ? ? if( s[i] == t[j] )

? ? ? ? ? ? { ++i; ++j }

? ? ? ? ? ? else

? ? ? ? ? ? { i = i - j + 1; j = 0; } ? ? ? ?/*通過回溯i指針并將j重新指向起始位置*/

? ? ? ? }

? ? ? ? if( j >= tlen )

? ? ? ? ? ? return i - j;

? ? ? ? else

? ? ? ? ? ? return -1;

? ? }

2.首位匹配算法

類似簡單算法,只是要先比較模式串t的首尾字符,首尾字符比較完后,再應用簡單算法比較中間字符

int Index_FL( char* s, char* t, int pos )

{

? ? int slen, tlen, patStart, patEnd;

? ? int i = pos, j, k;

? ??if( s == NULL || t == NULL )

? ? ? ? ? ? return -1;

? ? slen = strlen( s );

? ? tlen = strlen( t );

? ? if( tlen > slen || pos < 0 || pos > tlen - 1 )

? ? ? ? return -1;

? ? patStart = t[0];

? ? patEnd = t[ tlen - 1 ];

? ? while( i <= slen - tlen ) ? ? ? ?/*最后一個匹配位置為i = slen - tlen*/

? ? {

? ? ? ? if( s[i] != patStart ) ++i;

? ? ? ? else if( s[ i + tlen - 1 ] != patEnd ) ++i;

? ? ? ? else

? ? ? ? {

? ? ? ? ? ? k = 1; j = 1; ? ? ? ?/*用k來標記s中的位置, 以i + 1為起點*/

? ? ? ? ? ? while( j < tlen - 1 && s[ i + k ] == t[j] ) ? ? ? ?/*對中間字符串應用簡單算法進行匹配*/

? ? ? ? ? ? { j++; k++;?}

? ? ? ? ? ? if( j >= tlen - 1 ) ? ? ? ?/*由于末尾已經檢測過相等,所以當 j = tlen - 1時表明匹配*/

? ? ? ? ? ? ? ?return i;

? ? ? ? ? ? else ? ? ? ?/*不匹配則i右移一位*/

? ? ? ? ? ? ? ? i++;?

? ? ? ? }

? ? }

? ? return -1;

}

3.KMP算法,主要差別就在于,之前在遇到不匹配的情況時都是回溯s字符串的i指針,使用該算法則保持i不變,回溯t字符串的j指針,并且通過將t數組的首尾字串的重合位數記錄在next數組中,在匹配過程中,通過next數組的值,來確定j指針的回溯位置。(說的比較抽象,具體學習還是參看教材,我這里就是做個記錄便于以后復習或改進O(∩_∩)O)

紅色部分是跟原先算法主要的不同之處

void get_next( char* t, int next[] ) ? ? ? ?/*若不存在k使得‘p0...pk-1’ = ‘pj-k...pj-1’,則令next[j] = 0(原先算法是令這種情況的next值為1)*/

{

? ? int tlen;

? ? int i = 1, j = 0;

? ? next[0] = 0;

? ? next[1] = 0;

? ? tlen = strlen( t );

? ? while( i < tlen )

? ? {

? ? ? ? if( t[i] == t[j] )

? ? ? ? { ++i; ++j; next[i] = j; }

? ? ? ? else

? ? ? ? {

? ? ? ? ? ? j = next[j];

? ? ? ? ? ? if( j == 0?) ? ? ? ?/*j == 0則代表next[i + 1] = 0,即不存在k使得‘p0...pk’ = ‘pi-k...pi’*/

? ? ? ? ? ? ? ? next[++i] = 0;

? ? ? ? }

? ? }

}

?

int Index_KMP( char* s, char* t, int pos )

{

? ? ? ? int slen, tlen, i, j;

? ? ? ? int next[100];

? ? ? ??if( s == NULL || t == NULL )

? ? ? ? ? ? return -1;

? ? ? ? slen = strlen( s );

? ? ? ? tlen = strlen( t );

? ? ? ? get_next( t, next );

? ? ? ? if( tlen > slen || pos < 0 || pos > tlen - 1 )

? ? ? ? ? ? return -1;

? ? ? ? i = pos; j = 0;

? ? ? ? while( i < slen && j < tlen )

? ? ? ? {

? ? ? ? ? ? if( s[i] == t[j] ) { ++i; ++j; }

? ? ? ? ? ? else

? ? ? ? ? ? {

? ? ? ? ? ? ? ? if( j == 0 ) ? ? ? ?/*當s[i] != t[0]時直接將i移至下一位進行比較*/

? ? ? ? ? ? ? ? ? ? ++i;

? ? ? ? ? ? ? ? else

? ? ? ? ? ? ? ? ? ? j = next[j];

? ? ? ? ? ? }

? ? ? ? }

? ? ? ? if( j >= tlen )

? ? ? ? ? ? return i - tlen;

? ? ? ? else

? ? ? ? ? ? return 0;

}

? ??

轉載于:https://www.cnblogs.com/liangchao/archive/2012/09/20/2695233.html

總結

以上是生活随笔為你收集整理的KMP 算法——C的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。