#include <iostream>
#include <cstring>
using namespace std;
#define MaxSize 255
typedef struct {
char *ch;
int len;
}SString;
void Init(SString &str);//初始化串
bool StrAssign(SString & str, char*ch);//赋值操作
bool StrCopy(SString&str,SString T);//复制串
bool IsEmpty(SString str);//判空
int StrCompare(SString s1,SString s2);//串比较操作
bool Concat(SString &s,SString&s1,SString&s2);//串连接
bool SubString(SString str,SString&sub,int pos,int len);//返回指定位置指定长度的字串
bool Clear(SString&str);//清空字符串
bool Destory(SString&str);//销毁字符串
int index(SString &str,SString& t);//定位操作,若主串str和字串t有相同的字串,则返回他在这个主串首次出现的位置
void Print(SString str);//打印
///KMP算法
void GetNext(string t,int next[]);//获取next数组
//NEXT数组
int KmpNext(SString &str,SString& t);//定位操作,若主串str和字串t有相同的字串,则返回他在这个主串首次出现的位置
//NextVal数组
int KmpNextVal(SString &str,SString& t);
int main()
{
SString s1;SString s2;
char* ss1;char* ss2;
ss1="google";
ss2="googlogoogle";
Init(s1);Init(s2);
StrAssign(s1,ss1);
StrAssign(s2,ss2);
cout<<"s1:";
Print(s1);
cout<<endl;
cout<<"s2:";
Print(s2);
cout<<endl;
cout<<KmpNext(s2,s1)<<endl;
cout<<KmpNextVal(s2,s1)<<endl;
}
void GetNext(SString t,int next[])//获取next数组
{
int i=1,j=0;
next[1]=0;
while(i<t.len)
{
if(j==0||t.ch[i]==t.ch[j])
{
++i;++j;
}
else
j=next[j];
}
}
int KmpNext(SString &str,SString& t)//定位操作,若主串str和字串t有相同的字串,则返回他在这个主串首次出现的位置
{
int i=1,j=0;
int next[t.len+1];
GetNext(t,next);
while(i<=str.len&&j<=t.len)
{
if(j==0||str.ch[i]==t.ch[j])
{
i++;j++;
}
else
j=next[j];
}
if(j>t.len)
return i-t.len;
else
return 0;
}
int KmpNextVal(SString &str,SString& t)
{
int i=1,j=0;
int next[t.len+1];
GetNext(t,next);
int nextval[t.len+1];
nextval[1]=0;
for(int j=2;j<=t.len;j++)
{
if(t.ch[next[j]]==t.ch[j])
nextval[j]=nextval[next[j]];
else
nextval[j]=next[j];
}
while(i<=str.len&&j<=t.len)
{
if(j==0||str.ch[i]==t.ch[j])
{
i++;j++;
}
else
j=nextval[j];
}
if(j>t.len)
return i-t.len;
else
return 0;
}
void Init(SString &str)//初始化串
{
str.ch= nullptr;
str.len=0;
}
bool StrAssign(SString & str, char*ch)//赋值操作
{
if(str.ch)
{
free(str.ch);
str.ch=NULL;
}//释放原空间
int len=0;
char*c=ch;
while(*c)//计算ch串长度
{
++len;
++c;
}
if(len==0)
{
Init(str);
return false;
}
else
{
str.ch=(char*)malloc(sizeof(char)*len+1);
if(str.ch==NULL)return false;//空间分配失败
else{
for(int i=0;i<=len;i++)
str.ch[i]=ch[i];
str.len=len;
return true;
}
}
}
bool StrCopy(SString&str,SString T)//复制串
{
str.ch=(char*)malloc(sizeof(char)*(T.len+1));
for(int i=0;i<=T.len;i++)
{
str.ch[i]=T.ch[i];
}
str.len=T.len;
return true;
}
bool IsEmpty(SString str)//判空
{
return (str.len==0);
}
int StrCompare(SString s1,SString s2)//串比较操作
{
for(int i=0;i<s1.len&&i<s2.len;i++)
{
if(s1.ch[i]!=s2.ch[i])
return s1.ch[i]-s2.ch[i];
}
return s1.len-s2.len;
}
bool Concat(SString &s,SString&s1,SString&s2)//串连接
{
if(s.ch)
{
free(s.ch);
s.ch=NULL;
}
s.ch=(char*)malloc(sizeof(char)*(s1.len+s2.len+1));
if(s.ch==NULL)return false;//空间分配失败
else {
for (int i = 0; i < s1.len; i++) {
s.ch[i] = s1.ch[i];
}
for (int j = s1.len; j <= (s1.len + s2.len); j++)
s.ch[j] = s2.ch[j - s1.len];
s.len=s1.len+s2.len;
return true;
}
}
bool SubString(SString str,SString&sub,int pos,int len)//返回指定位置指定长度的字串
{
if(pos<0||pos>=str.len||len<0||pos+len>str.len)
return false;
if(sub.ch)
{
free(sub.ch);
sub.ch=NULL;
}
if(len==0)
{
sub.ch=NULL;
sub.len=0;
return true;
}
else
{
sub.ch=(char*)malloc(sizeof(char)*(len+1));
for(int i=pos-1,j=0;j<=len;i++,j++)
{
sub.ch[j]=str.ch[i];
}
sub.len=len;
return true;
}
}
bool Clear(SString&str)//清空字符串
{
if(str.ch)
{
free(str.ch);
str.ch=NULL;
}
str.len=0;
return true;
}
bool Destory(SString&str)//销毁字符串
{
if(str.ch)
{
free(str.ch);
}
return true;
}
int index(SString &str,SString& t)//定位操作,若主串str和字串t有相同的字串,则返回他在这个主串首次出现的位置
{
int i=0,j=0;
if(IsEmpty(t))return -1;
while(i<str.len&&j<str.len)
{
if(str.ch[i]==t.ch[j])
{
i++;
j++;
}
else
{
i=i-j+1;j=0;
}
}
if(j>=t.len)
return i-j+1;
else
return -1;
}
void Print(SString str)//打印
{
for(int i=0;i<str.len;i++)
{
cout<<str.ch[i];
}
}
结果