串,即字符串 是有零个或多个字符组成的有限序列 字符在主串中的位置:字符在串中的序号(位序从1开始;空格也是字符) 串的基本操作主要以子串作为操作对象 设计串的时候 ch[0]废弃
串,即字符串 是有零个或多个字符组成的有限序列
字符在主串中的位置:字符在串中的序号(位序从1开始;空格也是字符)
串的基本操作主要以子串作为操作对象
设计串的时候 ch[0]废弃不用,并且在末尾添加变量length记录串的长度。
ch[0]废弃不用:字符的位序和数组下标相同。但char之战1B也就是8bit,以功能存储0~255个数,空间有限。
串的存储
//串的顺序存储 #define MAXLEN 255 typedef struct{ //静态 char ch[MAXLEN]; int length; }SString; typedef struct{ //动态 char *ch; int length; }HString; HString S; S.ch = (char *)malloc(MAXLEN * sizeof(char)); S.length=0; //串的链式存储 typedef struct StringNode{ //char ch;//1B 存储密度低 char ch[4]; struct StringNode * next;//4B }StringNode,* String;
串的基本操作
//求子串 bool SubString(SString &Sub,SString S,int pos,int len){ //第pos个字符起是长度为len的子串,Sub返回想要找到的子串的内容 if(pos+len-1 > S.length)//判断子串是否越界 return false; for(int i=pos;i<pos+len;i++)//将Sub的值复制到ch数组里,并且把长度设为len Sub.ch[i-pos+1] = S.ch[i]; Sub.length = len; return true; } //比较串大小 若S>T 返回值>0,=<同理 bool 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 } //定位操作 若主串S中存在与子串T值相同的子串,则傅安辉它在主串中第一次出现的位置 int Index(SString S,SString T){ int i=1,n=StrLength(S),m=StrLength(T);//n表示S的长度 SString sub; while(i<=n-m+1){ SubString(sub,i,m); if(StrCompare(sub,T)!=0) ++i; else return i; } return 0; }
串的朴素模式匹配
子串:主串中存在的
模式串:想尝试在主串中寻找的串,未必存在
串的模式匹配:在主串中找到与模式串相同的子串,并返回其所在位置
// 串的朴素模式匹配 int Index(SString S,SString T){ int k=1;//指向当前主串中被遍历的字符,因为0号位弃之不用故从1开始 int i=k,j=1;//i k 共同指向S j指向T while(i<S.length && j<T.length)//若不匹配i就回溯 { if(S.ch[i]==T.ch[i]){ ++i; ++j }else{ k++; k=i; j=1;//若不相等j还指向模式串第一个位置 } } if(j>T.length) return k; else return 0; }
若模式创长度 为m,主串长度为n,则匹配成功的最好时间复杂度:O(m);匹配失败的最好时间复杂度:O(n);最坏的时间复杂度:O(nm)
KMP算法——朴素模式优化
//KMP算法 int Index_KMP(SString S,SString T,int next[]){ int i=1,j=i; while(i<=S.length && j<T.length){ 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; }