KMP算法(A + B for you again—HDU - 1867 )

KMP算法就是求母串中字串的長度或者字串出現的次數,相對於暴力求解的話,KMP算法節省時間,KMP算法就是分兩部分next[ ]和kmp中找字串。next[ ]算法是找字串中的前後綴的長度,這樣在KMP中尋找時就節省了時間。
next[ ]函數代碼:

void get_next(char s2[],int m)
{
	int i=1,j=0;
	nex[0]=-1;//初始next[0]=-1
	while(i<m)
	{
		if(j==-1||s2[i]==s2[j])
		{
			i++;
			j++;
			nex[i]=j;
		}
		else
			j=nex[j];
	}
}

KMP代碼:

int kmp(char str1[],char str2[])
{	
	int i=0,j=0,m;
	n=strlen(str1);
	m=strlen(str2);
	get_next(str2,m);
	while(i<n&&j<m)
	{
		if(j==-1||str1[i]==str2[j])//逐個取尋找
		{
			i++;
			j++;
		}
		else
			j=nex[j];
	}
}

例題解釋:

題目:

一般來說,字符串處理存在很多問題。現在你遇到另一個這樣的
問題。如果你得到兩個字符串,例如“asdf”和“sdfg”,它們之間的加法結果是“asdfg”,
“sdf”是“asdf”的尾子串和“sdfg”的頭子串。然而,結果是“asdfghjk”,
當你必須添加“asdf”和“ghjk”並保證最短的字符串,然後最小的詞典
第二,其他增加的規則相同。
輸入
對於每種情況,有兩個字符串(選擇的字符只是’a’到’z’),每個字符串的長度不超過10 ^ 5且不爲空。
輸出
打印本書的最終字符串。
Sample Input

asdf sdfg
asdf ghjk

Sample Output

asdfg
asdfghjk

解題思路: 給兩個字符串分別作爲母串和子串,輸出兩個和的最短字符串,如abcde+bcdekl結果爲abcdekl,就是找第一個字符串的後綴與第二個字符串的前綴相同的最大長度。 注意:如果兩個字符串不管誰做母串所得的前綴和後綴的最大長度都一樣,則就用strcmp()判斷最小字典輸出。

程序代碼:

#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
int nex[500000],n;
char s[500000],s1[500000];
void get_next(char s2[],int m)
{
	int i=1,j=0;
	nex[0]=-1;
	while(i<m)
	{
		if(j==-1||s2[i]==s2[j])
		{
			i++;
			j++;
			nex[i]=j;
		}
		else
			j=nex[j];
	}
}
int kmp(char str1[],char str2[])
{
	
	int i=0,j=0,m;
	n=strlen(str1);
	m=strlen(str2);
	get_next(str2,m);
	while(i<n&&j<m)
	{
		if(j==-1||str1[i]==str2[j])
		{
			i++;
			j++;
		}
		else
			j=nex[j];
	}
	if(i==n)
		return j;
	else
		return 0;
}
int main()
{
	int i,k1,k2,j;
	while(cin>>s>>s1)
	{
		k1=kmp(s,s1);
		k2=kmp(s1,s);//找出兩個最長的前綴和後綴相同的長度
		if(k1>k2)
		{
			cout<<s<<s1+k1<<endl;
		}
		else if(k1<k2)
		{
			cout<<s1<<s+k2<<endl;
		}
		else
		{
			if(strcmp(s,s1)<0)//按字典順序輸出
				cout<<s<<s1+k1<<endl;
			else
				cout<<s1<<s+k2<<endl;
		}
	}
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章