03--串

一、串的概念

  • 主要概念和术语
    • 串:是零个或多个字符组成的有限序列
    • 串值:双引号括起来的字符序列是串值
    • 串长:串中所包含的字符个数称为该串的长度
    • 空串:长度为零的串称为空串
    • 空格串(空白串):构成串的所有字符都是空格的串
  • 子串
    • 串中任意个连续字符组成的子序列称为该串的子串。
    • 空串是任意串的子串,任意串是其自身的子串
  • 字串的位置
    • 将子串在主串中首次出现时的该子串的首字符对应在主串中的序号
  • 串相等:
    • 如果两个串的串值相等,称两个串相等
  • 串变量和串常量
    • 串常量和整常数、实常数一样,在程序中只能被引用但不能改变其值,只能读不能写
    • 通常串常量是由直接量来表示的
    • 串变量和其它类型的变量一样,其值是可以改变

二、串

  • 串的ADT
ADT String{
    数据对象
    数据关系
    基本操作
    StrAssign(&t, chars);
    StrConcat(&s, t);
    StrLength(t);
    SubString(s, pos, len, &sub);
    StrCopy(&s, t);
    Strcmp(s, t);
    Replace(&s, t, v)
}
  • 串的主要存储方式
    • 定长顺序存储方式:将串定义成字符数组,利用串名可以直接访问串值。串的存储空间在编译时确定,其大小不能改变
    • 堆分配存储方式:仍用一组连续的存储单元来依次存储串中的字符序列,但串的存储空间是在程序运行时根据串的实际程度动态分配的。
    • 块链存储方式:是一种链式存储结构表示
    • 代码均参考线性结构,int类型换为char类型即为串

三、串模式匹配

  • 模式匹配:找子串在主串中的位置
    • 子串T在主串S中的定位称为模式匹配或串匹配。
    • 模式匹配成功是指在主串S中能够找到模式串T,否则,称模式串T在主串S中不存在
  • 暴力模式匹配( O ( m n ) O(mn) O(mn))
int IndexString(StringType s, StringType t){
    int k, j;
    k = 0, j = 0;
    while((k<s.length) && (j<t.length)){
        if(s[k] == t[j]){
            k++;
            j++;
        }
        else{
            k = k - j +1;
            j = 0;
        }
    }
    if(j == t.length)
    return (k - t.length);
    else
    return -1;
}
  • KMP算法
int KMP_index(char* s, char* t){
    int i = 0, j = 0;
    while((i < s.len) && (k < t.len){
        if(j == -1 || s[i] == t[j]){
            i++;
            j++;
        }
        else
        j = next[j];
    }
    if(j >= t.len)
    return i - t.len;
    else
    return -1;
}
  • KMP算法关键是构建next数组,寻找最长的相同首尾子串,脑算时:next[j]为拿出0–j-1的字符,长为j-1,j-2,…,1挨个试,首尾相等,最终的长度就是next[j]的值。
  • 穷举法
//借用char *subString(s, stratpos, len)
int next1(char* t, int j){
    // 0 < j < t.len
    char *str1, *str2;
    int k = j;
    do{
        k--;
        str1 = subString(t, 0, k);
        str2 = subString(t, j-k, k);
    }while(k && strncmp(str1, str2, k))
    if(k == 0)
    return 0;
    else
    return k;
}
  • 改进穷举法
int next2(char *t, int j){
    // 0 < j < t.len
    for(int k = j - 2; k >= 0; --k){
        if(t[k] == t[j - 1])
            if(strncmp(t, &t[j - k - 1], k + 1) == 0)
            return k + 1;
    }
    return 0;
}
  • 递推算法 next(j) = next(j-1) + 1
void next3(char* t, int next[]){
    int k, j = 2;
    next[0] = -1;
    next[1] = 0;
    while(j < t.len){
        k = next[j - 1];
        while(k > 0 && t[k] != t[j - 1])
            k = next[k];
        if(k <= 0)
            if(t[0] == t[j - 1])
                next[j] = 1;
            else
                next[j] = 0;
        else
            next[j] = k + 1;
        j++;
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值