目录
一、类型
1.定长类型
typedef struct{
char ch[MAXLEN];
int length;
}SString;
2.堆分配
//堆分配
typedef struct{
char*ch;
int length;
}HString;
3.链表类型
//链表类型
typedef struct StringNode{
char ch[4]; //是存储密度更大,一个结点保存多个字符,假设为4
StringNode*next;
}StringNode,*String;
二、功能函数,以定长类型为主
1)求子串,从第pos为长度为len的子串,返回给sub
bool SubString(SString &sub, SString s, int pos, int len)
{
//为了方便将pos和下标统一起来,从下标为1开始存储
if(pos+len-1>s.length)
return false;
for(int i=1,j=pos;j<=pos+len-1;i++,j++){
sub.ch[i]=s.ch[j];
}
sub.length=len;
return true;
}
2)给字符串赋值为ch
bool StrAssign(SString &s, char *ch)
{
int i=0;
//计算ch的长度
while (ch[i]!='\0')
i++;
//从1开始赋值
for(int j=1;j<=i;j++){
//ch是从0开始,s是从1开始
s.ch[j]=ch[j-1];
}
s.length=i;
return true;
}
3)比较字符串大小
int StrCompare(SString s, SString t)
{
for(int i=1;i<=s.length && i<=t.length;i++){
if(s.ch[i]!=t.ch[i])
return s.ch[i]-t.ch[i];
}
return s.length-t.length;
}
4)找子串位序
int FindSubindex(SString s, SString t)
{
//从第一个开始取长度为t.length那么长的子串,分别和t对比
for(int i=1;i<=s.length-t.length+1;i++){
SString sub;
SubString(sub,s,i,t.length);
if(StrCompare(sub,t)==0)
return i;
}
return 0;
}
5)简单模式匹配
int index_simple(SString s, SString t)
{
int i=1,j=1;
while (i<=s.length && j<=t.length) {
if(s.ch[i]==t.ch[j])
i++,j++;
else {
i=i-j+2;
j=1;
}
}
if(j>t.length)
return i-t.length;
else
return 0;
}
6)KMP算法
1.求next数组
void get_next(SString T,int next[]){
int i=1,j=0;
//所有next数组,第一个都是0
next[1]=0
while(i<T.length){
if(j==0 ||T.ch[i]==T.ch[j]){
++i,++j;
next[i]=j;
}
else
j=next[j];
}
}
2.KMP
void index_KMP(SString S,SString T,int *next){
int i=1,j=1;
while (i<=s.length && j<=T.length) {
//比简单匹配算法多了个j==0的判断
if(j==0||s.ch[i]==T.ch[j])
i++,j++;
else {
//和简单匹配算法的不同
j=next[j];
}
}
if(j>T.length)
return i-T.length;
else
return 0;
}
3.优化的next数组nextval
void get_nextval(SString T,int nextval[]){
int i=1,j=0;
//所有next数组,第一个都是0
next[1]=0
while(i<T.length){
if(j==0 ||T.ch[i]==T.ch[j]){
++i,++j;
//改进
if(T.ch[i]!=T.ch[j])
nextval[i]=j;
else
nextval[i]=nextval[j];
}
else
j=next[j];
}
}