串的知识点

目录

1.串的定义(空串、字串、空格串)

2.串的各种基本操作

2-1:串的定义存储

2-2:串的赋值操作

2-3:串的长度操作

2-4:串的比较操作(串排序应用中的核心操作)

2-5:串连接操作

2-6:求子串操作

2-7:串清空操作

3.串的模式匹配

3-1:简单模式匹配

3-2:KMP算法

3-3:KMP算法的改进


1.串的定义(空串、字串、空格串)

1-1:串是由零个或多个字符组成的有限序列。   (限定了元素为字符的线性表)

1-2:空串:含有零个字符。

1-3:子串:串(主串)中任意连续字符组成的子序列

1-4:空格串:由一个或者多个空格组成的串(空格串不是空串)

2.串的各种基本操作

2-1:串的定义存储

定长顺序存储表示

typedef struct {

    char str[maxSize+1];  // 多出一个'\0'作为结束标记

    int length;

}Str;

变长分配存储表示

typedef struct {

    char *ch;  // 指向动态分配存储区首地址的字符指针

    int length;  // 串长度

}Str;

2-2:串的赋值操作

int strassign(Str& str, char* ch) {

    if (str.ch) 

        free(str.ch);  // 释放原空间

    int len = 0; char *c = ch;

    while (*c) {  // 求ch串的长度

        ++len;

        ++c;

    }

    if (len == 0) {  // 如果ch为空串,则直接返回空串

        str.ch = nullptr;

        str.length = 0;

        return 1;

    }

   else {

        str.ch = (char*)malloc(sizeof(char)*(len+1));  // 取len+1是为了多分配一个空间存放'\0'

        if (str.ch == null) // 分配失败

             return 0;  

        else {

            c = ch;

            for (int i = 0; i <= len; ++i, ++c)   // 之所以取<=也是为了将'\0'复制过去

                str.ch[i] = *c;   

            str.length = len;

            return 1;

             }  

      }  

}

2-3:串的长度操作

int strlength(Str str) {

    return str.length;

}

2-4:串的比较操作(串排序应用中的核心操作)

int strcompare(Str s1, Str s2) {

    for (int i = 0; i < s1.length && i < s2.length; ++i) {

        if (s1.ch[i] != s2.ch[i]) return s1.ch[i] - s2.ch[i];

    }

    return s1.length - s2.length;

}

2-5:串连接操作

int concat(Str &str, Str str1, Str str2) {

    if (str.ch) {

        free(str.ch);  // 释放原空间

        str.ch = nullptr;

    }

    str.ch = (char*)malloc(sizeof(char)*(str1.length+str2.length));

    if (str.ch == null)

         return 0;

    int i = 0;

    while (i < str1.length) {

        str.ch[i] = str1.ch[i];  

        ++i;

    }

    int j = 0;

    while (j <= str2.length) {

        str.ch[i+j] = str2.ch[j];  // 之所以取<=也是为了将'\0'复制过去

        ++j;

    }

    str.length = str1.length + str2.length;

    return 1;  

}

2-6:求子串操作

int substring(Str& substr, Str str, int pos, int len) {

 if (pos<0 || pos>=str.length || len<0 || len>str.length-pos) return 0;

    if (substr.ch) {

        free(substr.ch);

        substr.ch = null;

    }

    if (len == 0) {

        substr.ch = null;

        substr.length = 0;

        return 1;

    } else {

      substr.ch = (char*)malloc(sizeof(char)*(len+1));

        int i = pos;  int j = 0;

        while (i<pos+len) 

            substr.ch[j++] = str.ch[i++];

        substr.ch[j] = '\0';

        substr.length = len;

        return 1;  

    }  

}

2-7:串清空操作

int clearstring(Str& str) {

    if (str.ch) {

        free(str.ch);

        str.ch = null;

    }

    str.length = 0;

    return 1;

}

3.串的模式匹配

配合视频食用更佳:https://www.bilibili.com/video/BV1EE411378s?from=search&seid=10131997502735647979 

看完上面这个视频以后,再跟着下面这个视频过一遍:https://www.bilibili.com/video/BV1D441147y8?from=search&seid=13404547156312995020

3-1:简单模式匹配

int index(Str str, Str substr) {

    int i = 1, j = 1, k = i;

    while (i<=str.length && j<=substr) {

        if (str.ch[i] == substr[j]) {

            ++i;

            ++j;

        } else {

            j = 1;

            i = ++k;  // 匹配失败,i从主串的下一位置开始,k中记录了上一次的起始位置

        }   }

    if (j>substr.length)

       return k;

    else

       return 0;  

}

3-2:KMP算法

求next数组的代码

void GetNext(char* p,int next[])

{

    int pLen = strlen(p);

    next[0] = -1;

    int k = -1;

    int j = 0;

    while (j < pLen - 1)

    {

        //p[k]表示前缀,p[j]表示后缀

        if (k == -1 || p[j] == p[k])

        {

            ++k;

            ++j;

            next[j] = k;

        }

     else

        {

            k = next[k];

        }   

    }   

}

KMP算法

int KMP(char* s, char* p, int next[])

{

    int i = 0;  int j = 0;

    int sLen = strlen(s),pLen = strlen(p);

    while (i < sLen && j < pLen)

    {//①如果j = -1,或者当前字符匹配成功(即S[i] == P[j]),都令i++,j++

        if (j == -1 || s[i] == p[j])

        {

            i++;

            j++;

        }

else  {//②如果j != -1,且当前字符匹配失败(即S[i] != P[j]),则令 i 不变,j = next[j]

//next[j]即为j所对应的next值

            j = next[j];

        }

    }

    if (j == pLen)

    return i - j;  // 匹配成功,则返回匹配的位置

    else

        return -1; }

3-3:KMP算法的改进

void GetNextval(char* p, int next[])

{

    int pLen = strlen(p);

    next[0] = -1;

    int k = -1;

    int j = 0;

    while (j < pLen - 1)

    { //p[k]表示前缀,p[j]表示后缀

        if (k == -1 || p[j] == p[k])

        {

            ++j;

            ++k;

            if (p[j] != p[k])//较之前next数组求法,改动在下面4行

            next[j] = k;   //之前只有这一行

         else {       //因为不能出现p[j] = p[ next[j ]],所以当出现时需要继续递归,k = next[k] = next[next[k]]

             next[j] = next[k]; }else {

            k = next[k];

        }  }  }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值