字符串的定义和基本操作
字符串的定义和相关术语
- 串:即
字符串(String)
,由零个或多个字符组成的有限序列
- 子串:
串中
任意个连续
的字符组成的子序列
- 主串:包含子串的串
- 字符在主串中的位置:字符在串中第一次出现的序号
- 子串在主串中的位置:子串的第一个字符在主串中的位置
- 串 和 线性表:
关系:
串是一种特殊的线性表,数据元素之间呈线性关系,有位序
区别:
串的数据对象限定为字符集(各种字符)
串的基本操作对象通常为子串
字符串的基本操作
赋值
操作StrAssign
:把串S赋值为MY复制
操作StrCopy
: 串S复制得到串T判空
操作StrEmpty
:判断串S是否为空串- 求
串长StrLength
:返回串S中的字符个数即串长 清空
操作StrClear
:将串S清为空串销毁
串StrDestory
:将串S销毁- 串
连接Concat
:串S1和串S2连接成串T - 求
子串SubString
:返回串S的第pos个字符起长度为len的子串 定位
操作Index
:返回子串Sub在主串S中的位置比较
操作StrCompare
:比较两个字符串的大小,如果S>T,则返回值>0;若S=T,则返回值=0;若S<T,则返回值<0
字符串的实现(顺序存储结构)
顺序串的定义
#define MAXLEN 255
typedef struct{
char ch[MAXLEN];
int len;
}SString;
typedef struct{
char ch*;
int len;
}HString;
HString S;
S.ch=(char *)malloc(MAXLEN*sizeof(char));
S.len=0;
字符串的基本操作
bool StrAssign(SString &T,char *chars){
int i;
if (StrLenth(chars)>MAXLEN))
return false;
else{
T.ch[0]=StrLenth(chars);
for(i=1;i<=T.ch[0];i++){
T.ch[i]=*(chars+i-1);
}
return true;
}
}
bool StrCopy(SString &T,SString S){
int i=0;
if (StrLenth(S)>MAXLEN)
return false;
else
for (i=0;i<=StrLenth(S);i++){
T.ch[i]=S.ch[i];
}
return true;
}
bool StrEmpty(SString S){
if (StrLenth(S)==0)
return true;
else
return false;
}
int StrLenth(SString S){
return S.ch[0];
}
bool StrClear(SString &S){
if (StrLenth(S)==0)
return false;
else
S.ch[0]==0;
return true;
}
bool StrDestory(SString &S){
int i;
if (StrLenth(S)==0)
return false;
else{
for(i=1;i<=StrLenth(S);i++){
free(S.ch[i]);
}
StrClear(S);
return true;
}
}
bool Concat(SString &T,SString S1,SString S2){
int i;
if(StrLenth(S1)+StrLenth(S2)<=MAXLEN){
for(i=1;i<=StrLenth(S1);i++){
T.ch[i]=S1.ch[i];
}
for(i=1;i<=StrLenth(S2);i++){
T.ch[i+StrLenth(S1)]=S2.ch[i];
}
StrLenth(T)=StrLenth(S1)+StrLenth(S2);
return true;
}
else
return false;
}
字符串的特殊操作
bool SubString(SString &Sub, SString S, int pos, int len){
if((pos+len-1)>S.ch[0])
return false;
for(i=pos;i<(pos+len);i++){
Sub.ch[i-pos+1]=S.ch[i];
}
Sub.len=Sub.ch[0]=len;
return true;
}
int StrCompare(SString S, SString T){
for(int i=1;i<=S.ch[0] && i<=T.ch[0];i++){
if (S.ch[i]!=T.ch(i))
return S.ch[i]-T.ch(i);
}
return S.ch[0]-T.ch(0);
}
int Index(SString S, SString T){
int i=1, n=StrLenth(S),m=StrLenth(T);
SString sub;
while(i<n-m+1){
SubString(sub,S,i,m);
if(StrCompare(sub,T)!=0)
++i;
else
return i;
}
return 0;
}
字符串的实现(链式存储结构)
typedef struct StringNode{
char ch[4];
struct StringNode *next;
}StringNode,*LinkStringNode;
字符串的模式匹配算法
- 什么是模式匹配:搜索关键字(文件、搜索引擎),即子串的定位操作
- 术语:
主串S
和模式串T
主串:被搜索的字符串
模式串:要搜索出的字符串
- 字符串模式匹配:在
主串中找到
与模式串相同的子串
,并返回其所在位置
子串:主串的一部分,一定存在的
模式串:不一定能在主串中找到
ex: 主串S = “Google”。找到T = “gle”这个子串的位置。
字符串的朴素模式匹配算法
- 朴素模式匹配算法:
主串长度
为n
,模式串长度
为m
,将主串中所有长度为m的子串依次与模式串对比
,直到找到一个与模式串完全匹配的子串,或所有的子串都不匹配为止
- 策略:比较普通比较暴力的模式匹配算法
从目标串s的第一个字符(指针i)起和模式串t的第一个字符(指针j)进行比较
若相等,则继续逐个比较后续字符;
若当前子串匹配失败,则主串指针i指向下一个子串的第一个位置(i-i+2),模式串指针j回到模式串第一个位置,直至串t 中的每个字符依次和串s的一个连续的字符序列相等,则称模式匹配成功,此时串t的第一个字符在串s 中的位置就是t 在s中的位置;
否则模式匹配不成功。
- 复杂度:最坏的情况下,算法的时间复杂度为O(n*m) ,n和m分别为主串和模式串的长度;最好的情况下,时间复杂度为O(n)
朴素模式匹配算法的实现
int Index(SString S,SString T){
int i=1,j=1;
while(i<=S.lengh && j<=T.lengh){
if(S.ch[i]==T.ch[j]){
++i;
++j;
}
else{
i=i-j+2;
j=1;
}
}
if(j>T.lengh)
return i-T.lengh;
else
return 0;
}