#include<iostream>
#include<string>
using namespace std;
const int SIZE = 200;
static int Count1 = 0;
static int Count2 = 0;
class sString
{
private:
char str[SIZE]={'\0'};
int length = 0;
int* next = nullptr;
public:
friend ostream& operator<<(ostream&, sString&);
friend istream& operator>>(istream&, sString&);
friend sString operator+(sString&, sString&);
sString(){}
~sString()
{
delete[] next;
this->Clear();
}
sString(const sString* one)
{
for (int i = 0; i < one->length ; i++)
{
str[i] = one->str[i];
length++;
}
}
sString(const char* s)
{
int i = 0;
while (s[i] != '\0')
{
str[i] = s[i];
i++;
length++;
}
}
sString(string s)
{
for (int i = 0; i < s.length(); i++)
{
str[i] = s[i];
length++;
}
}
bool Isempty()
{
if (this->length == 0)
return true;
else
return false;
}
int Length()
{
return this->length;
}
void Clear()
{
for (int i = 0; i < this->length; i++)
{
str[i] = '\0';
}
}
sString& Concat(sString& one)
{
int i = this->length;
int j = 0;
for (i, j; j < one.length; j++, i++)
{
str[i] = one.str[j];
length++;
}
return (*this);
}
sString& Concat(string& one)
{
int i = this->length;
int j = 0;
for (i, j; j < one.length(); i++, j++)
{
str[i] = one[j];
length++;
}
return (*this);
}
sString& Concat(const char* one)
{
int i = this->length;
int j = 0;
while (one[j] != '\0')
{
str[i] = one[j];
i++;
j++;
length++;
}
return (*this);
}
sString Substring(int len, int loc)
{
if (len + loc - 1 > this->length)
exit(1);
sString newone;
int j = 0;
int i = 0;
for (j = 0,i = loc - 1; i < len + loc - 1; i++,j++)
{
newone.str[j] = str[i];
newone.length++;
}
return newone;
}
bool Isequal(sString& one)
{
bool flag = true;
if (one.length != this->length)
{
flag = false;
return false;
}
for (int i = 0; i < this->length; i++)
{
if (one.str[i] != this->str[i])
{
flag = false;
return false;
}
}
if (one.length == this->length && flag == true)
return true;
}
int Index(sString& one) //朴素模式匹配算法
{
if (one.length > this->length)
return 0;
int i = 0;
int j = 0;
for (i = 0, j = 0; i < this->length && j < one.length; i++)
{
Count1++;
if (this->str[i] == one.str[j])
j++;
else
{
i = i - j;
j = 0;
}
}
if (j == one.length)
return i - one.length+1;
else
return 0;
}
int Index_Kmp(sString& one)//KMP算法
{
one.Getnext();
int i = 0;
int j = 0;
while (i < this->length && j < one.length)
{
Count2++;
if (j == -1 || this->str[i] == one.str[j])
{
i++;
j++;
}
else
{
j = one.next[j];
}
}
if (j == one.length)
return i - j + 1;
else
return -1;
}
void Getnext()//创建next数组
{
this->next = new int[this->length];
next[0] = -1;
int k = -1;//next[j]==k,k为相同的前缀(和后缀)字符串长度,str[k]为前缀
int j = 0;//str[j]为后缀
while (j < this->length - 1)
{
if (k == -1 || this->str[j] == this->str[k])
{
k++;
j++;
next[j] = k;
}
else
{
k = next[k];
}
}
}
void Printnext()
{
if (this->next == nullptr)
this->Getnext();
for (int i = 0; i < this->length; i++)
{
cout << this->next[i] << ' ';
}
cout << endl;
}
};
ostream& operator<<(ostream& os, sString& s)
{
os << s.str << endl;
return os;
}
istream& operator>>(istream& os, sString& s)
{
string one;
getline(cin, one);
for (int i = 0; i < one.length(); i++)
{
s.str[i] = one[i];
s.length++;
}
return os;
}
sString operator+(sString& one, sString& two)
{
sString newone;
int i = 0;
int j = 0;
for ( i = 0; i < one.length; i++)
{
newone.str[i] = one.str[i];
newone.length++;
}
for (i, j = 0; j < two.length; i++, j++)
{
newone.str[i] = two.str[j];
newone.length++;
}
return newone;
}
int main()
{
sString s1, s2;
cout << "input string:";
cin >> s1;
cout << "input substring:";
cin >> s2;
int num1 = s1.Index(s2);
int num2 = s1.Index_Kmp(s2);
s1.Printnext();
s2.Printnext();
cout << "num1= " << num1 << " num2= " << num2;
cout << "count1= " << Count1 << " count2= " << Count2;
return 0;
}
串的基本操作与Kmp算法
于 2022-08-15 21:22:39 首次发布