5.2堆串
为了解决定长顺序串的截断问题,引出不限定串长动态分配的堆串
5.2.1类型构造
typedef struct
{
char * ch;
int len; // 串长度
} HString;
5.2.2串赋值
//将字符串tval的值赋给串s
StrAssign(HString * s ,char * tval) {
if(s->ch!=NULL) free(s->ch); //将s置空
i=0; while(tval[i]!=‘\0’) i++; //
len=i;计算t串长
if(len){
s->ch=(char *)malloc(len);
for(i=0;i<len;i++) s->ch[i]=tval[i];
}
else s->ch=NULL; //t串为空
s->len=len;//别忘了设置串长
return(1);
}
5.2.3串插入
将T插入在S第pos个字符之前
StrInsert(HString *s,int pos,HString *t){
if(pos<1||pos>s->len+1||s->len==0||t->len==0)//检验是否合法
return(0);
temp=(char *)malloc(s->len+t->len);
// 复制S前串,T串,S后串
for(i=0;i<pos-1;i++)
temp[i]=s->ch[i];
for(i=0;i<t->len;i++)
temp[i+pos-1]=t->ch[i];
for(i=pos-1;i<s->len;i++)
temp[i+t->len]=s->ch[i];
free(s->ch);
s->ch=temp; s->len+=t.len;
return(1);
}
5.3链串
存储密度=数据元素所占存储位/实际分配的存储位
5.3.1结点类型
#define BLOCK_SIZE 80
typedef struct Block {
char ch[ BLOCK_SIZE ];
struct Block *next;
}Block;
5.3.2块链串类型
typedef struct { // 串的链表结构
Block *head, *tail; // 串的头,和尾指针(方便串的连接操作)
int length; // 串长
}BLString;
5.3.3子串的定位
子串称为模式串
5.3.3.1简单模式匹配算法
主串s的第pos个字符起和模式串的第一个字符向后逐一比较
//串采用定长顺序存储结构
int Index(Sstring *S, Sstring *T,int pos) {
i=pos-1;//主串S的下标
j=0;//子串T的下标
while(i<S->len&&j<T->len)
{ if(S->ch[i]==T->ch[j]) { i++; j++; }
else { i=i-j+1; j=0; }
}
if(j==T->len) return i-T->len+1; //主串S中刚出现子串的下标
else return 0;
}
5.3.3.2改进模式匹配算法(KMP)
next[j]:
当模式串中下标为j的字符
与主串相应字符"失配"时,
在模式串中需重新和
主串中该字符进行比较的
字符的位置
-1 当j=0时 (特殊情况)
next[j]= max{ k|0<=k<j且p0…pk-1=pj-k…pj-1 }
0 其它 (和模式串的第1个字符进行比较)
j 0 1 2 3 4 5 6 7
模式串 a b a a b c a c
next[j] -1 0 0 1 1 2 0 1
j 0 1 2 3 4
模式串 a b c a c
next[j] -1 0 0 0 1
int Index_KMP(SString *S,SString *T,int pos) {
i=pos-1; j=0;
while(i<S->len&&j<T->len) {
if(j==-1) { i++; j=0; }
if(S->ch[i]==T->ch[j]) { i++; j++; }
else j=next[j];
}
if(j==T->len) return i-T->len+1;
else return 0;
}