KMP演算法的next、next value陣列程式碼實現及POJ3461
昨天中午弄懂了陣列的手工計算方法之後,根據書上例題解出了一道KMP演算法的匹配題。
我用了next 和nextval兩種解決方法,其實就是陣列實現的程式碼片不同。
w表示給定的模式字串
next陣列程式碼實現如下:
int next[maxw],j=0,i;
next[0]=-1;
next[1]=0;
for(i=2; i<=strlen(w); ++i)
{
while(j>=0&&w[j]!=w[i-1])
j=next[j];
next[i]=++j;
}
nextval陣列程式碼實現如下:
int nextval[maxw],i=0,j=-1;
nextval[0]=-1;
while(i<strlen(w))
{
if(j==-1||w[i]==w[j])
{
++i;
++j;
if (w[i]!=w[j])
nextval[i]=j;
else
nextval[i]=nextval[j];
}
else
j=nextval[j];
}
下面貼一道POJ上的例題:
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 29204 | Accepted: 11704 |
Description
The French author Georges Perec (1936–1982) once wrote a book, La disparition, without the letter 'e'. He was a member of the Oulipo group. A quote from the book:
Tout avait Pair normal, mais tout s’affirmait faux. Tout avait Fair normal, d’abord, puis surgissait l’inhumain, l’affolant. Il aurait voulu savoir où s’articulait l’association qui l’unissait au roman : stir son tapis, assaillant à tout instant son imagination, l’intuition d’un tabou, la vision d’un mal obscur, d’un quoi vacant, d’un non-dit : la vision, l’avision d’un oubli commandant tout, où s’abolissait la raison : tout avait l’air normal mais…
Perec would probably have scored high (or rather, low) in the following contest. People are asked to write a perhaps even meaningful text on some subject with as few occurrences of a given “word” as possible. Our task is to provide the jury with a program that counts these occurrences, in order to obtain a ranking of the competitors. These competitors often write very long texts with nonsense meaning; a sequence of 500,000 consecutive 'T's is not unusual. And they never use spaces.
So we want to quickly find out how often a word, i.e., a given string, occurs in a text. More formally: given the alphabet {'A', 'B', 'C', …, 'Z'} and two finite strings over that alphabet, a word W and a text T, count the number of occurrences of W in T. All the consecutive characters of W must exactly match consecutive characters of T. Occurrences may overlap.
Input
The first line of the input file contains a single number: the number of test cases to follow. Each test case has the following format:
- One line with the word W, a string over {'A', 'B', 'C', …, 'Z'}, with 1 ≤ |W| ≤ 10,000 (here |W| denotes the length of the string W).
- One line with the text T, a string over {'A', 'B', 'C', …, 'Z'}, with |W| ≤ |T| ≤ 1,000,000.
Output
For every test case in the input file, the output should contain a single number, on a single line: the number of occurrences of the word W in the text T.
Sample Input
3
BAPC
BAPC
AZA
AZAZAZA
VERDI
AVERDXIVYERDIAN
Sample Output
1
3
0
這道題就是求匹配過程中子串在主串中出現了多少次。
next版:
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int maxw=10000+10;
const int maxt=1000000+10;
int match(char w[],char s[],int next [])
{
int cnt=0,p=0,cur=0,slen,wlen;
slen=strlen(s);
wlen=strlen(w);
while(cur<slen)
{
if(s[cur]==w[p])
{
++cur;
++p;
}
else if(p>=0)
{
p=next[p];
}
else
{
++cur;
p=0;
}
if(p==wlen)
{
++cnt;
p=next[p];
}
}
return cnt;
}
int main()
{
int loop;
scanf("%d",&loop);
while(loop--)
{
char w[maxw],t[maxt];
scanf("%s%s",w,t);
int next[maxw],p=0,cur;
next[0]=-1;
next[1]=0;
for(cur=2; cur<=strlen(w); ++cur)
{
while(p>=0&&w[p]!=w[cur-1])
p=next[p];
next[cur]=++p;
}
printf("%d\n",match(w,t,next));
}
return 0;
}
nextval版:
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int maxw=10000+10;
const int maxt=1000000+10;
int match(char w[],char s[],int next [])
{
int cnt=0,p=0,i=0,slen,wlen;
slen=strlen(s);
wlen=strlen(w);
while(i<slen)
{
if(s[i]==w[p])
{
++i;
++p;
}
else if(p>=0)
{
p=next[p];
}
else
{
++i;
p=0;
}
if(p==wlen)
{
++cnt;
p=next[p];
}
}
return cnt;
}
int main()
{
int loop;
scanf("%d",&loop);
while(loop--)
{
char w[maxw],t[maxt];
scanf("%s%s",w,t);
int nextval[maxw],i,j;
i=0;
nextval[0]=-1;
j=-1;
while(i<strlen(w))
{
if(j==-1||w[i]==w[j])
{
++i;
++j;
if (w[i]!=w[j])
nextval[i]=j;
else
nextval[i]=nextval[j];
}
else
j=nextval[j];
}
printf("%d\n",match(w,t,nextval));
}
return 0;
}
比較記憶體佔用和執行時長,發現就這道題而言,nextval的用時要少但是記憶體佔用較多。
總之,nextval是對next優化改進後的方法,效率會提高。
我對KMP演算法的初步學習大概就是這麼多認識,當然是木有BF演算法那麼好理解,但是KMP又快又好用阿~~
希望我能就這麼堅持下去吧,即使腦子木有人家那麼靈活但是如果多花花時間能弄出來我也是挺開心噠~~
相關文章
- KMP演算法的next、next value陣列的手工計算KMP演算法陣列
- KMP演算法以及優化(程式碼分析以及求解next陣列和nextval陣列)KMP演算法優化陣列
- kmp 演算法簡介及 next 陣列推導KMP演算法陣列
- KMP演算法的Next陣列詳解KMP演算法陣列
- KMP演算法next陣列的深入理解KMP演算法陣列
- KMP演算法中關於next陣列的探究KMP演算法陣列
- 關於 KMP next 陣列的應用KMP陣列
- KMP演算法中我對獲取next陣列的理解KMP演算法陣列
- [資料結構]KMP演算法(含next陣列詳解)資料結構KMP演算法陣列
- BZOJ 3670 [Noi2014]動物園 (KMP next陣列應用)KMP陣列
- POJ 2406-Power Strings(重複子串-KMP中的next陣列)KMP陣列
- POJ 2752+KMP+利用next陣列性質求出所有相同的字首和字尾KMP陣列
- PHP 陣列current和next用法分享PHP陣列
- vue的nextTick的實現Vue
- Get_Next的VB程式碼
- mysql實現nextVal功能MySql
- 圖解KMP字串匹配演算法+程式碼實現圖解KMP字串匹配演算法
- 原始碼解讀-vue是如何實現$nextTick的原始碼Vue
- kmp演算法實現原理及簡單示例KMP演算法
- jQuery next()方法程式碼例項jQuery
- Node.js 程式碼閱讀筆記系列 — process.nextTick() 的實現Node.js筆記
- LeetCode演算法題-Next Greater Element I(Java實現)LeetCode演算法Java
- KMP演算法 Java實現KMP演算法Java
- jquery next()方法使用程式碼例項jQuery
- Next Blockchain System架構實現-bitswapBlockchain架構
- C語言 二維陣列實現三子棋的思路及程式碼C語言陣列
- Abp Vnext Vue3 的版本實現Vue
- yield next和yield* next的區別
- 如何實現資料庫資料到Abp vnext實體物件的同步?以及程式碼生成工具資料庫物件
- JS陣列去重演算法實現JS陣列演算法
- Vue原始碼閱讀一:說說vue.nextTick實現Vue原始碼
- jQuery實現的多個陣列合並程式碼例項jQuery陣列
- javascript實現的合併兩個陣列程式碼例項JavaScript陣列
- ABP vnext模組化架構的最佳實踐的實現架構
- nextTick的原理及執行機制
- 圖解 KMP 演算法(JavaScript 實現)圖解KMP演算法JavaScript
- 陣列排序的實現陣列排序
- javascript實現複製一個陣列程式碼例項JavaScript陣列