一:代码实现
#include<iostream>
using namespace std;
const int MAXSRTINGLEN=50;
class NewString
{
private:
char Mystring[MAXSRTINGLEN + 1];
char Teststring[MAXSRTINGLEN + 1];
int Mystringlength;
int Teststringlength;
int next[100000]={0};
public:
NewString();
~NewString()
{
}
int BFstring(int pos);
int KMPstring(int pos);
void GetValNext();
void Display();
};
int NewString::KMPstring(int pos)
{
int m = Mystringlength; int n = Teststringlength;
GetValNext();
int i = 0, j = 0;
while (i < m && j < n)
{
if (j == -1 || Mystring[i] == Teststring[j])
{
i++; j++;
}
else
{
j = next[j];
}
}
if (j == n)
{
return i - j;
// return -1;
}
else
{
return -1;
}
}
void NewString::GetValNext()
{
next[0] = -1;
int i = 0; int j = -1;
while (i < Teststringlength - 1)
{
if (j == -1 || Teststring[i] == Teststring[j])
{
i++;
j++;
next[i] = j;
}
else
{
j = next[j];
}
}
}
NewString::NewString()
{
int i=0;
char temp;
while (cin>>temp)
{
if (temp == '0')
{
break;
}
Mystring[i] = temp;
i++;
}
Mystring[i + 1] = '\0';
Mystringlength = i;
i = 0;
char temp1;
while (cin >> temp1)
{
if (temp1 == '0')
{
break;
}
Teststring[i] = temp1;
// cout << temp;
i++;
}
Teststring[i + 1] = '\0';
Teststringlength = i;
next[Teststringlength] = { 0 };
// cout << i << endl;
//GetValNext();
}
int NewString::BFstring(int pos)
{
int i = pos; int j = 0;
while (i < Mystringlength && j < Teststringlength)
{
// cout << Mystring[i] << Teststring[j] << endl;
if (Mystring[i] == Teststring[j])
{
i++; j++;
// cout << Mystring[i] ;
// cout << i << " " << j << endl;
}
else
{
i = i - j + 1;
j = 0;
}
}
//cout << j << endl;
if (j >= Teststringlength)
{
return i - Teststringlength;
}
else
{
return -1;
}
}
void NewString::Display()
{
for (int i = 0; i < Mystringlength; i++)
{
cout << Mystring[i]<<" ";
}
cout << endl;
for (int i = 0; i < Teststringlength; i++)
{
cout << Teststring[i] << " ";
}
cout << endl;
}
int main(void)
{
NewString *s = new NewString;
s->Display();
cout <<"BF匹配位置是" << s->BFstring(0) << endl;
cout << "KMP匹配的位置是" << s->KMPstring(0) << endl;
//cout << 1;
return 0;
}
二:原理:
2.1:BF算法
基本思想:
从主串S的第0个字符开始和模式T 的第0个字符进行比较, 若相等,则继续比较两者的后续字符; 否则,从主串S的第1个字符开始和模式T 的第0个字符进行比较, 重复上述过程,直到T 中的字符全部比较完毕,则说明本趟匹配成功;或S中字符全部比较完,则说明匹配失败。
说明:模式匹配过程要进行多趟的匹配,每趟匹配要进行若干次的比较
1. 在串S和串T中设比较的起始下标i和j;
2. 循环直到S或T的所有字符均比较完;
2.1 如果S[i]==T[j],继续比较S和T的下一个字符;
2.2 否则,将i和j回溯(i=i-j+1,j=0),准备下一趟比较;
3. 如果T中所有字符均比较完,则匹配成功,返回匹配的起始比较下标(i-j);否则,匹配失败,返回-1;
2.1:KMP算法
结论: i可以不回溯,模式向右滑动到的新next[j]的算法分析: k=next[j-1](由next[]的 定义可以知道:t0t1…tk-1= tj-k…tj-3tj-2) 1. 如果t[k]==t[j-1]或k==-1(不存在长度相同的前缀子串和左子串)则t0t1…tk-1tk= tj-k…tj-3tj-2tj-1,因此 next[j]=k+1,next[j]计算结束 否则, 查找t0t1…tk的最长左子串 k=next[k],转 1 继续执行
比较起点k ,并且k 仅与模式串T有关!