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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

算法-发明KMP算法的唐纳德·克努特是怎么想到失配函数next[j]的?

發(fā)布時間:2024/3/26 编程问答 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 算法-发明KMP算法的唐纳德·克努特是怎么想到失配函数next[j]的? 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

背景

字符串模式匹配,普通模式非常好理解,拿著模式串依次與主串做比較,知道完全匹配,但是這種算法,主串得不斷地回溯,時間復(fù)雜度O(n*m)。




唐納德·克努特

有沒有降低時間復(fù)雜度的可能,唐納德·克努特等人想到了一種辦法不用使主串不停地回溯,而每次使模式串的某個字符與主串的待比較字符對齊,這個算法簡稱KMP。求解模式串的哪個字符該與這次比較的主串字符對齊,是KMP算法的核心,簡稱next函數(shù)或失配函數(shù)。這種算法求解復(fù)雜度降低到O(n+m)。

next函數(shù)語義

next[j]=k表達(dá)的意思是從模式串的 1~j-1 組成的子模式串,最長相同的前、后綴的長度為 k-1。舉例說明,如下的字符串,next[6]=3,因為編號為6的字符c的最長前綴為編號為1的a ,編號為2的b 字符,最長后綴為編號為4的字符,編號為5的字符b,所以 k=3。

12345678
abaabcac

再看一下失配函數(shù)next[j]的嚴(yán)格定義,模式串字符的編碼從1開始。



next函數(shù)分析

next 函數(shù)值僅取決于模式串本身而與相匹配的主串無關(guān)。從next函數(shù)的定義出發(fā)用遞推的方法求next函數(shù)值。

由定義得知 next[1]=0,設(shè)next[j]=k,這表明在模式串中存在下列關(guān)系

"P1...Pk-1" = "Pj-k+1...Pj-1"

圖形化顯示(一條豎線表示一個字符):



其中k為滿足1 < k < j的某個值,并且不能存在k’ > k滿足上個等式。此時 next[j+1]=? 分兩種情況討論,

1)若 Pk = Pj ,則 next[j+1] = next[j] + 1 ,即 k + 1 ,如下圖顯示:



2)若Pk不等于Pj,如下圖所示,我們把如下字符,看成一個字符串,尋找它的最長相同的前、后綴:

"P1...Pj+1"



此時我們已知一個條件:

"P1...Pk-1" = "Pj-k+1...Pj-1"

也就是在上圖中2個黃色區(qū)域表示的前、后綴字符串相等,這樣我們依然在上圖中的左側(cè)黃色部分中尋找。最終找到了2塊咖啡色區(qū)域 1~k’-1, k-k’+1~k-1 相等,根據(jù)next函數(shù)的定義,便是:

next[k]=k'



并且我們根據(jù)已知條件 ‘P1…Pk-1’ = ‘Pj-k+1…Pj-1’,可以推導(dǎo)出在右側(cè)黃色區(qū)域也存在這樣的咖啡色區(qū)域,根據(jù)等式傳遞,我們可以得出:

"P1...Pk'-1" = "Pj-k'+1...Pj-1"

因為Pj不等于Pk,所以我們新找出了一個k’(很顯然1 < k’ < k),如果它真的滿足了 Pj=Pk’,則 next[j+1] = k’ + 1 ,即 :

next[j+1] = next[k] + 1

如果它很遺憾地又不等于Pj,也沒關(guān)系,我們繼續(xù)在[1,k’]這個區(qū)間內(nèi)找這樣的K點,如果真的不存在這樣的k’,那么 根據(jù)定義可以得出:

next[j+1]=1

失配函數(shù)代碼實現(xiàn)

/// <summary>/// 失配函數(shù)/// </summary>/// <param name="p">模式字符串(編碼從索引位置1開始)</param>/// <returns>模式字符串中每個字符的失配值數(shù)組</returns>private static int[] getNext(char[] p){int[] next = new int[p.Length];next[1] = 0;int j = 1;int k = 0;while (j < p.Length - 1){if (k == 0 || p[j] == p[k]){next[++j] = ++k; //上述分析中的k'+1賦值給next[j+1]}else{k = next[k]; //next[k]賦值給k,相當(dāng)于上述分析中的k'}}return next;}

模擬分析

模擬失配函數(shù)求解的整個過程代碼。

static void Main(string[] args){string pattern = "abaabcac";char[] pcharsfrom1 = preOperate(pattern);Console.WriteLine();int[] next = getNextWithTest(pcharsfrom1);printf(next);Console.ReadLine();}

預(yù)處理字符串,將字符串整體后移1位

/// <summary>/// 預(yù)處理字符串,將字符串整體后移1位/// </summary>/// <returns></returns>private static char[] preOperate(string pattern){char[] pchars = pattern.ToCharArray(0, pattern.Length);char[] pcharsfrom1 = new char[pchars.Length + 1];for (int i = pchars.Length; i > 0; i--)pcharsfrom1[i] = pchars[i - 1];return pcharsfrom1;} private static int[] getNextWithTest(char[] p){int[] next = new int[p.Length];next[1] = 0;int j = 1;int k = 0;printf(p);while (j < p.Length - 1){if (k != 0)Console.WriteLine("p[{0}]({1}) == p[{2}]({3})??", j, p[j], k, p[k]);if (k == 0 || p[j] == p[k]){if (k == 0){++j;++k;next[j] = k;Console.WriteLine("根據(jù)k=0得出:p[{0}]={1}", j, k);Console.ForegroundColor = ConsoleColor.DarkGreen;Console.WriteLine("--------------------------------");Console.ForegroundColor = ConsoleColor.White;}else{++j;++k;next[j] = k;Console.WriteLine("根據(jù)p[j] == p[k]得出:p[{0}]={1}", j, k);Console.ForegroundColor = ConsoleColor.DarkGreen;Console.WriteLine("--------------------------------");Console.ForegroundColor = ConsoleColor.White;}}else{k = next[k];}}return next;}private static void printf<T>(T[] p){int eachlineCount = 10;for (int line = 0; line < p.Length / eachlineCount + 1; line++){for (int i = 0; i < eachlineCount && line * eachlineCount + i < p.Length; i++){Console.Write(" {0} ", line * eachlineCount + i);}Console.Write("\n");for (int i = 0; i < eachlineCount && line * eachlineCount + i < p.Length; i++){if (line == 0)Console.Write(" {0} ", p[line * eachlineCount + i]);else{Console.Write(" {0} ", p[line * eachlineCount + i]);}}Console.Write("\n\n");}}

模擬結(jié)果展示:


源碼下載:

http://download.csdn.net/detail/daigualu/9791023

總結(jié)

以上是生活随笔為你收集整理的算法-发明KMP算法的唐纳德·克努特是怎么想到失配函数next[j]的?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 国产又粗又长 | 人人爱人人澡 | 自拍偷拍色综合 | 日本一级黄色录像 | 美女黄污网站 | 最近中文字幕在线观看视频 | 人人草网 | 久久视频在线看 | 国产外围在线 | 全部免费毛片在线播放 | 嫩草伊人| 美女隐私免费观看 | www.国产com | 美女网站免费视频 | 少妇人妻真实偷人精品视频 | 亚洲日本精品一区 | 中文字幕精品一区二 | av天天操 | 亚洲国产综合av | 97色综合| 精品国产乱码久久久久久闺蜜 | 啪啪无遮挡 | 久久婷婷av | 超碰极品 | 成人午夜在线观看视频 | 全国最大色 | 国产东北女人做受av | 国产精品久久婷婷六月丁香 | 全国男人的天堂网 | 91精品国产乱码久久久久 | 狼友视频国产精品 | 粉嫩av一区二区三区免费观看 | 福利视频一二区 | 国产精品无码网站 | 精品一区视频 | 色哟哟中文字幕 | 国产美女黄色片 | 日本老太婆做爰视频 | 欧美一区免费 | 东京热av一区| 日日夜夜国产 | 娇妻之欲海泛舟无弹窗笔趣阁 | 成人免费在线网址 | 麻豆视频网站在线观看 | 国产精品国产三级国产专播品爱网 | 亚洲中文无码久久 | ,午夜性刺激免费看视频 | 免费看60分钟黄视频 | 日日爱886 | 91福利网| 国产精品久久久久久69 | 福利av在线 | 日本v视频 | 欧美xxxx黑人xyx性爽 | 动漫美女隐私无遮挡 | japanese国产在线观看 | 亚洲 欧美 自拍偷拍 | 国产呦小j女精品视频 | 亚洲一区免费在线 | 亚洲另类自拍 | 黄色片网站国产 | 欧美日韩1区2区3区 亚洲日本精品视频 | 欧美天天爽 | 国内精品嫩模av私拍在线观看 | 成人黄色短片 | 自拍第二页 | 亚洲欧美在线看 | xxx国产在线观看 | 狠狠操很很干 | 狠狠干天天干 | av黄在线观看 | 亚洲天堂一区 | 在线免费黄色片 | 日日夜夜撸啊撸 | 成人自拍视频 | 免费一区二区视频 | 最新国产网址 | 青青青操 | 亚洲av无码片一区二区三区 | 性综艺节目av在线播放 | 欧洲精品无码一区二区 | 极品美女啪啪 | 久久精品区 | 被警察猛c猛男男男 | 国产精品入口a级 | 亚洲av无码一区二区三区在线播放 | 在线观看网站黄 | 国产精品免费一区二区三区四区 | 亚洲精品乱码久久久久久9色 | 强开小受嫩苞第一次免费视频 | 超碰97av| 国产激情毛片 | 麻豆视| 夜夜操夜夜摸 | 青青草超碰在线 | 成人影视免费观看 | 三级在线网址 | 99久久精品国产一区二区成人 | 波多野结衣av一区二区全免费观看 |