1. 程式人生 > >KMP演算法next陣列計算方法的優化

KMP演算法next陣列計算方法的優化

KMP演算法的原理就是利用相匹配的字首子串與字尾子串,來確定失配時下次對齊的位置;

其中最關鍵的就是next陣列的確立;

資料結構課本上KMP演算法next陣列計算經典的例子:

void getNext(const char *pStr, int *nextArr)
{
	int i = 0, k = -1, pLen = strlen(pStr);
	nextArr[i] = k;
	int mLen = pLen - 1;
	while (i < mLen)
	{
		if (k == -1 || pStr[i] == pStr[k])
		{
			nextArr[++i] = ++k;
		}
		else k = nextArr[k];
	}
}

而這個KMP演算法next陣列計算只關注了前k-1個字元中,前後匹配的子串,沒有利用到當前失配的字元;

比如:ABACA,當第2個A失配時,說明被匹配串的當前位置的字元必定不等於A,所以將第0位對齊到此位也必定失配,所以應該繼續回溯到第0位失配時所需要對齊的位,這裡也就是-1;

這個"必定不等於(!=)"是可以被利用的!我們對KMP演算法next陣列計算的優化正是基於此;

廢話不多說,下面是優化後的KMP演算法next陣列計算與註釋:

//優化過後的next陣列求法
void getNext(const char *pStr, int *nextArr)
{
	int j = 0, j_next = -1, pLen = strlen(pStr);
	nextArr[j] = j_next;//此處第0位失配,則對齊第-1位;
	int mLen = pLen - 1;
	while (j < mLen)
	{
		//基於第j位與第j_next已經相等(或者j_next為-1)
		//廣義地將空字元(pStr[-1])看做可以與任意字元相等,這樣很益於理解
		//求下一個j失配時的對齊位
		if (pStr[++j] != pStr[++j_next])
		{
			//因為(自增++之後)pStr[j]與pStr[j_next]不相等
			//所以此時pStr[j]失配後,可以用pStr[j_next]來試試,所以nextArr[j] = j_next;
			nextArr[j] = j_next;
			//因為此時pStr[j]與pStr[j_next]不相等
			//所以回溯取pStr[j_next]失配時的對齊位pStr[nextArr[j_next]]
			//直到相等為止
			while (j_next != -1 && pStr[j] != pStr[j_next]) j_next = nextArr[j_next];
		}
		//這裡就是優化點
		//因為(自增++之後)pStr[j]與pStr[j_next]相等
		//所以pStr[j]失配後,pStr[j_next]也必定失配
		//故丟棄pStr[j_next],再取pStr[j_next]失配時的對齊位pStr[nextArr[j_next]]
		//也即nextArr[j] = nextArr[j_next];
		else nextArr[j] = nextArr[j_next];
	}
}

給個無註釋純淨版的(KMP演算法next陣列計算):

void getNext(const char *pStr, int *nextArr)
{
    int j = 0, j_next = -1, pLen = strlen(pStr);
    nextArr[j] = j_next;
    int mLen = pLen - 1;
    while (j < mLen)
    {
        if (pStr[++j] != pStr[++j_next])
        {
            nextArr[j] = j_next;
            while (j_next != -1 && pStr[j] != pStr[j_next]) j_next = nextArr[j_next];
        }
        else nextArr[j] = nextArr[j_next];
    }
}

歡迎拍磚與指正!


相關推薦

KMP演算法next陣列計算方法優化

KMP演算法的原理就是利用相匹配的字首子串與字尾子串,來確定失配時下次對齊的位置; 其中最關鍵的就是next陣列的確立; 資料結構課本上KMP演算法next陣列計算經典的例子: void getNext(const char *pStr, int *nextArr) {

KMP演算法NEXT陣列計算方法

KMP演算法: 關鍵是利用匹配失敗後的資訊,儘量減少模式串與主串的匹配次數以達到快速匹配的目的。具體實現就是實現一個next()函式,函式本身包含了模式串的區域性匹配資訊。時間複雜度O(m+n)。

KMP演算法Next陣列計算

KMP演算法是在最近這兩年的軟體設計師考試中才出現的。2次都是讓求Next函式的序列(其實是)。先看看題吧。(2011年下半年上午題)(2012年上半年上午題)其實做這個題很簡單,我先說說這個題裡的各種概念。給定的字串叫做模式串T。j表示next函式的引數,其值是從1到n。而

KMP演算法next陣列計算的理解——菜鳥福音

我的文章莫名找不到了。。。還是再寫一遍吧,希望對了解KMP的演算法有點幫助…… 首先寫幾點 1)本文討論的KMP主要是嚴蔚敏的《資料結構》中第四章提到的KMP,即帶NEXT[]輔助陣列的KMP演算法 2)本文主要是討論KMP演算法NEXT[]陣列的計算的理

KMP演算法next陣列的手工計算方法

KMP是三位大牛:D.E.Knuth、J.H.Morris和V.R.Pratt同時發現的。其中第一位就是《計算機程式設計藝術》的作者!! KMP演算法要解決的問題就是在字串(也叫主串)中的模式(pattern)定位問題。說簡單點就是我們平時常說的關鍵字搜尋。模式

KMP演算法--Next陣列詳解與優化

本篇文章直接跳過蠻力演算法以及一些簡單背景,著重討論Next陣列的意義以及其是如何工作的,並對如何求Next陣列做詳細記錄。 1.背景 1.1 KMP演算法的應用:KMP演算法用來解決模式串匹配問題。 1.2 為什麼要用KMP演算法:普通的蠻力演算法時間複雜度為O(n*

KMP演算法next陣列計算

//求next陣列 private static void get_next(String T,int[] next){ int i=1,j=0; next[0]=0; while(i<T.length()){ while(j>0&&

KMP演算法--next陣列的解釋

前言 KMP演算法,我個人感覺還有是有寫難度的,我想了兩天才大概想明白(我想說的是,你們也可能想了好久還是想不明白,沒事,別放一下,有空了就想一想,一定要一鼓作氣拿下它)。其主要就是那個所謂的 next[ ] 陣列的構建,而其關鍵又是這一步 k=next[k-1],這一步想通了就沒有什麼

KMP演算法next陣列活用之前後綴問題

前置技能 KMP字串匹配演算法: KMP字串匹配演算法 正如題目中描述: 你的任務是找出一個字串s,s既是String的字首,又是String的字尾,並且s也出現在String的中間部分(既不是字首,也不是字尾),s的長度越長越好。 很明顯這是一道KMP演算法周邊題目,說是KMP演

超詳細理解:kmp演算法next陣列求解過程和回溯的含義

前言 KMP演算法是用來求一個較長字串是否包含另一個較短字串的演算法。具體演算法下一篇寫吧,這篇主要解釋next陣列的求解。 程式碼 程式碼應該都看過了,先貼在這裡,其中最難理解的地方就是求next陣列,以及k往前回溯,這也是寫本文的目的。 in

比較好懂的KMP演算法解釋(附next陣列求解方法

字串匹配是計算機的基本任務之一。   舉例來說,有一個字串"BBC ABCDAB ABCDABCDABDE",我想知道,裡面是否包含另一個字串"ABCDABD"?   許多演算法可以完成這個任務,Knuth-Morris-Pratt演算法(簡稱KMP)是最常用的之一。它以

簡單易懂的KMPNEXT陣列,BF演算法(例項講解)!!!

去了360面試,問了一個關於KMP的知識點,呀,完全忘了啊,太不應該了,然後就打算看看這個KMP,,, 看了好多關於KMP演算法的書籍和資料,總感覺沒有說的很清楚,為什麼會產生next陣列,為什麼給出了那麼簡短的程式,沒有一個過程,而有的帖子雖然next及其字串匹配說的很清

來去學習之---KMP演算法--next計算過程

一、概述 KMP演算法是一種字串匹配演算法,比如現有字串 T:ABCDABCDABCDCABCDABCDE, P:ABCDABCDE P字串對應的next值:[0,0,0,0,1,2,3,4,0] 二、匹配過程 判斷T字串是否包含P字串?下面看一下KMP的比較過程:   三、next陣列計算過程

POJ 2752 Seek the Name, Seek the Fame(KMPnext陣列)

【連結】http://poj.org/problem?id=2752 【題意】給個字串,求這個串所有字首與字尾相同的所有綴長度 【思路】 其實kmp裡的next這個微妙的陣列本身就是答案了,至於為什麼,我是用以前不知道哪裡弄來的的kmp模板試了一下看出來的【喂

【HDU - 1867 】A + B for you again(KMPnext陣列應用)

題幹: Generally speaking, there are a lot of problems about strings processing. Now you encounter another such problem. If you get two strings, such

KMPnext陣列定義

KMP演算法的Next陣列詳解 轉載請註明來源,幷包含相關連結。 網上有很多講解KMP演算法的部落格,我就不浪費時間再寫一份了。直接推薦一個當初我入門時看的部落格吧: http://www.cnblogs.com/yjiyjige/p/3263858.html 這位同學用詳細的

KMP演算法 next nextval函式

#include<malloc.h> #include<string.h> void get_next(SString T,int next[]) { int i=1,j=0,next[1]=0; while(i<T.length) {

KMP演算法失效函式計算演算法筆記

KMP演算法是經典的字串匹配演算法,在序列時時間複雜度為線性。KMP演算法的思想很簡單,將參與匹配的模式串部分視為週期串(最短)後接字首串,週期串重複出現次數記為K,週期串長度記為L。當模式串的第j位與正文串第k位比較時(假設模式串首位與正文串第x位比較),如果字元不相同,最

Kmpnext陣列含義

湊個字數 這篇分析了Kmp中next陣列到底是用來幹什麼的。文章假定大家已經對字串匹配演算法具有初步瞭解。但是對kmp中的next不是很懂。如果想要研究更多。可以出門左轉https://blog.csdn.net/qq_41105401/article/det

KMPnext陣列實現程式碼

next陣列求解: 以1開始,next[1]=0,next[2]=1,next[n] :將前面n-1個字元,計算從首尾開始組成最大的相同子串的長度,如果找到,那麼next值是該長度加1,否則next值是1。 void getNext(char *p,in