美文网首页
数据结构(四)串

数据结构(四)串

作者: AdRainty | 来源:发表于2021-08-22 00:48 被阅读0次

    4.1 串的定义

    字符串简称串,是一种由零个或多个字符多个字符组成的有限序列


    串.png

    S = "a_1a_2\cdots a_n" (n \ge 0)

    • 字串:串中任意个来纳许的字符组成的子序列
    • 主串:包含子串的串
    • 字串在字符中的位置:字符在串中的序号
    • 字串在主串中的位置:字串第一个字符在主串中的位置

    1、字串的任意个,即n可以为0
    2、字符串的位序从1开始而不是从0开始
    3、空格也算一个字符

    4.2 串的基本操作

    StrAssign(&T, chars) 赋值,把串T赋值为chars
    StrCopy(&T,S) 复制,由串S复制得串T
    StrEmpty(S) 判空
    StrLength(S) 求串长,即S的元素个数
    ClearString(&S) 清空,将S清为空串
    DestotyString(&S) 销毁串,将S销毁,回收存储空间
    Concat(&T, s1, s2) 串连接,用T返回s1和s2连接的字符串
    SubString(&Sub, S, pos, len)求字串,用Sub返回串S第pos个字符起长度为len的字串
    Index(S,T)定位,若S中存在T相同字串,返回第一次出现的位置,否则返回0
    StrCompare(S,T), 比较,若S>T返回>0,若S<T,返回<0

    4.3 串的存储结构

    4.3.1 顺序存储

    4.3.1.1 初始化

    typedef struct {
        char ch[MaxSize];
        int length;// 串实际长度
    }SString;
    

    4.3.1.2 求字串

    bool SubString(SString S, SString * sub, int pos, int len)
    {
        // 首先判断子串是否包含在当前字符串内
        if (pos + len  -1 > S.length) return false;
        for (int i = pos; i < pos+len; i++)
        {
            sub.ch[sub.pos+1] = S.ch[i];
        }
        sub.length = len;
        return true;
    }
    

    4.3.1.3 比较

    int 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;
    }
    

    4.3.1.4 定位

    int Index(SString S, SString T)
    {
        int i = 1; n = StrLength(S), m =StrLength(T)
        SString sub;
        while (i < n-m+1)
        {
            SubString(S, &sub, i, m);
            if (StrComp(T, sub) != 0) i++;
            else return i;
        }
        return 0;
    }
    

    4.3.2 堆分配存储结构

    typedef struct{
            char *ch;
            int length;
    } HString;
    
    HString S;
    S.ch = (Char *) malloc (Maxlen * sizeof(char));
    S.length = 0;
    

    4.3.3 块链存储

    typedef struct StringNode{
            char ch[4];
            struct StringNode *next;
    }StringNode,  *String;
    

    4.4 串的模式匹配

    子串是主串的一部分,一定存在,模式串不一定能在主串中找到

    4.4.1 朴素模式匹配算法

    int Index(SString S, SString T)
    {
        // 定义两个指针分别指向主串和模式串,主要通过改变两个指针而不需要去进行串操作
        int i = 1,j = 1;
        while (i < S.length && j < T.length) {
            if (S.ch[i] == T.ch[j]) {
                i++;
                j++;
            }
            else {
                i = i - j + 2;
                j = 1;
            }
        }
        if (j == T.length) return i - T.length + 1;
        else return 0;
    }
    

    最多对比n-m+1次
    时间复杂度为O(nm)

    4.4.2 KMP算法

    void Index_KMP(SString S, SString T, int pos){
        // i 目标串指针,j 模式串指针
        i = pos; j = 1;
        while( i <= length(S) && j <= length(T)){
            // 如果将要和 目标串元素 匹配的元素是模式串首元素前一位的元素
            // 当前目标串元素 和 模式串元素可以匹配
            // if (j == first_indexof(T) - 1 || S[i] == T[j]){
            if(j == 0 || S[i] == T[j]){
                // 指针各自右移一位,这也是为什么j==0时需要放在一起判断的原因
                ++i;
                ++j;
            }else{
                // 发生了失配,查Next数组移动模式串指针
                j = next[j];
            }
        }
        if (j > length(T)){
            // 如果模式串指针溢出了(模式串指针匹配完毕了所有模式串中的元素)
            return i - length(T);
        }
        else return 0;
    }
    

    KMP算法主要掌握手算next数组的方法,其中next[1]=0,next[2]=1

    相关文章

      网友评论

          本文标题:数据结构(四)串

          本文链接:https://www.haomeiwen.com/subject/vfrebltx.html