3.27
定长字符串
分配或复制
int StrAssign(StringPtr s, CHAR *t) {
int i;
for (i = 0; i < MAXLEN && t[i] != '\0'; ++i)
s->ch[i] = t[i];
return s->len = i;
}
void StrCopy(StringPtr s, StringPtr t) {
for (int i = 0; i < t->len; ++i)
s->ch[i] = t->ch[i];
s->len = t->len;
}
插入
bool StrInsert(StringPtr s, int pos, StringPtr t) { //将s在pos位插入t
if (pos < 0 || pos > s->len || t->len == 0)
return false;//插入失败
int mstart, mend, cend; //m为要移动的字符串
if (s->len + t->len <= MAXLEN) {
mstart = s->len + t->len - 1;
mend = pos + t->len;
cend = mend;
} else if (pos + t->len <= MAXLEN) {
mstart = MAXLEN - 1;
mend = pos + t->len;
cend = mend;
} else {
mstart = -1;
mend = 0;
cend = MAXLEN - 1;
}
int i;
for (i = mstart; i >= mend; --i)
s->ch[i] = s->ch[i - t->len];
for (i = pos; i < cend; ++i)
s->ch[i] = t->ch[i - pos];
s->len += t->len;
return true;
}
在插入时会有局限
超出部分截断
定长串在复制,插入等操作时有局限,引入堆串heapstring
堆串:动态删除内存,需要自己进行管理
定长串:长度不变
分配
int StrAssign(StringPtr s, CHAR *t) {
s->len = strlen(t);
s->ch = (CHAR*)malloc();
strncpy(s->ch,t,s->len);
return s->len;
}
shallow copy浅复制:共享内存,头部指向了新的
deep copy深复制:
复制
void StrCopy(StringPtr s, StringPtr t) {
// 如果目标字符串 s 的长度与源字符串 t 的长度不同,则需要重新分配内存
if (s->len != t->len) {
// 释放 s 原有的内存空间
free(s->ch);
// 重新分配足够的内存空间
s->ch = (CHAR*)malloc();
// 更新 s 的长度
s->len = t->len;
}
// 复制字符串内容
strncpy(s->ch, t->ch, t->len);
}
块链串
模式匹配:主串中搜索子串是否存在,返回其位置
brute-force暴力算法
概率均匀情况下,只与字串长度有关
kmp算法
next数组:匹配失败时,子串可以跳过的字符个数-------相同前后缀的长度
为什么找前后缀呢,基本出于巧合,如果1在匹配失败前匹配成功,那么2=1,如果此时3也等于2,则子串可以跳过2、3长度的单位,因为之前前面匹配都成功了,则4=3
如果当前字符相同,则同时递增i,j
如果不相同,则j按照next数组的步数回退,在这i永不递减
从中间劈开,对比前后缀