《数据结构》天勤和王道 第四章 串

  • 天勤部分
    • 1. 串的基础
      • 1.1 逻辑结构
      • 1.2 存储结构
      • 1.3 赋值操作
      • 1.4 串比较
      • 1.5 串连接
      • 1.6 求子串
      • 1.7 清空串
    • 2. KMP算法手工求解next数组
    • 3. KMP算法代码
    • 4. 求解nextval数组及代码
  • 王道的部分
    • 1. 串的定义和基本操作
    • 2. 串的存储结构
      • 2.1 串的顺序存储
      • 2.2 串的链式存储
      • 2.3 基本操作的实现
        • 2.3.1 求子串
        • 2.3.2 比较操作
        • 2.3.3 定位操作
      • 2.4 朴素模式匹配算法
      • 2.5 KMP算法
      • 2.6 KMP算法 求next数组(手算)
      • 2.7 next数组的优化(nextval数组)

天勤部分

1. 串的基础

1.1 逻辑结构

1.2 存储结构


1.3 赋值操作

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){       //即使传进来的是空串,也可以进行赋值操作 str.ch=NULL;str.length==0;return 1; }else{str.ch=(char*)malloc(sizeof(char)*(len+1));    //长度包括结束符 if(str.ch==NULL){      //如果分配空间失败,则返回0 return 0;}else{c=ch;for(int i=0;i<=len;++i,++c){   //把ch的结束符也赋进去 str.ch[i]=*c;}str.length=len;    return 1;}}
}

1.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;
}

1.5 串连接

int concat(Str& str,Str str1,Str str2){if(str.ch){free(str.ch);str.ch=NULL;}str.ch=(char*)malloc(sizeof(char)*(str.length+str2.length+1));if(!str.ch){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]=str.ch[j];++j;}str.length=str1.length+str2.length;return 1;
}

1.6 求子串

int subString(Str& substr,Str str,int pos,int len){   //pos为子串的起始下标,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];++i;++j;}substr.ch[j]='\0';substr.length=len;return 1;}
}

1.7 清空串

int clearString(Str& str){if(str.ch){     //如果串非空则清空 free(str.ch);str.ch=NULL;}str.length=0;return 1;
}

2. KMP算法手工求解next数组

KMP算法是为了从主串中快速地找到想要的子串。

当扫描到这种,一般情况下,会把指针回溯指向主串的第二个元素。

如这样:

但是这样造成效率低下,所以KMP就为了来解决这个问题。KMP可以仅仅比较模式串,并且让指针不回溯。

当指针之前与主串匹配时,此时模式串中有公共前后缀AB。就可以直接移动模式串到前缀与后缀一样的位置上继续进行比较。

而找公共前后缀时的条件是找最长的且长度要小于当前指针指向元素前面的子串的长度的公共前后缀。

这里模式串下标从1开始,不过具体可以看题目要求。

当扫描到六号位时,此时指针前面的子串的最大公共前后缀是ABA,长度为3。



3. KMP算法代码

//求next数组的代码
void getNext(Str substr,int next[]){int j=1,t=0;next[1]=0;   //无脑写0while(j<str.length){     //注意这里不能是小于等于,因为①语句j+1会越界    if(t==0||substr.ch[j]==substr.ch[t]){next[j+1]=t+1;   //① ++t;++j;}else{t=next[t];}}
}
//KMP算法
int KMP(Str str,Str substr,int next[]){   //str为主串,substr为模式串 int i=1,j=1;while(i<=str.length&&j<=substr.length){if(j==0||str.ch[i]==substr.ch[j]){++i;++j;}else{j=next[j];}} if(j>substr.length){return i-substr.length;}else{return 0;}
}

4. 求解nextval数组及代码


直接拿上面求next数组的代码进行修改。

void getNextval(Str substr,int nextval[],int next[]){int j=1,t=0;next[1]=0;   //无脑写0nextval[1]=0;while(j<str.length){     //注意这里不能是小于等于,因为①语句j+1会越界    if(t==0||substr.ch[j]==substr.ch[t]){next[j+1]=t+1;   //①if(substr.ch[j+1]!=substr.ch[next[j+1]]){nextval[j+1]=next[j+1];}else{nextval[j+1]=nextval[next[j+1]];} ++t;++j;}else{t=nextval[t];}}
}

再精简一下:

void getNextval(Str substr,int nextval[]){int j=1,t=0;nextval[1]=0;while(j<str.length){       if(t==0||substr.ch[j]==substr.ch[t]){if(substr.ch[j+1]!=substr.ch[next[j+1]]){nextval[j+1]=t+1;}else{nextval[j+1]=nextval[t+1];} ++t;++j;}else{t=nextval[t];}}
}

王道的部分

1. 串的定义和基本操作







2. 串的存储结构

2.1 串的顺序存储


2.2 串的链式存储

2.3 基本操作的实现

2.3.1 求子串

2.3.2 比较操作


这个跟天勤的一样,不懂可以看上面的。

2.3.3 定位操作


2.4 朴素模式匹配算法









2.5 KMP算法


朴素模式匹配算法在每次匹配失败后,指向主串的指针总要回溯。影响了总体效率,所以有了KMP算法。








注意一下当第一个元素就匹配失败的情况



代码如下:


2.6 KMP算法 求next数组(手算)

这个有两种方法:一种是王道讲的这个;一种是天勤上面讲的,根据当前要判断的元素的前面的模式串的子串中公共前后缀的长度加1来确定当前next数组的值(不过要注意模式串下标,有的题目是j从0开始,然后这里需要加1是因为next数组第一个是0,第二个是1)。


例如当第三个元素不匹配时,看模式串前两个元素,公共前后缀长度为0,加1就是1,所以next[3]=1。


当第四个元素不匹配时,此时模式串前三个元素的公共前后缀是“a”,长度是1,所以加1后是2,即next[4]=2。以此类推。




2.7 next数组的优化(nextval数组)

举个例子:




KMP算法不用改变,只是优化next数组,形参也使用优化后的nextval数组。

上面的描述可能有点绕,可以看下面的例子:

《数据结构》天勤和王道 第四章 串相关推荐

  1. c语言实现bf算法的定位函数,数据结构c语言版严蔚敏清华大学出版社第四章串.ppt...

    数据结构c语言版严蔚敏清华大学出版社第四章串 模式匹配(定位) 设有主串S和子串T(将S称为目标串,将T称为模式串),在主串S中,从位置start开始查找,如若在主串S中找到一个与子串T相等的子串,则 ...

  2. 数据结构(C语言)第二版 第四章课后答案

    数据结构(C语言)第二版 第四章课后答案 1~5 B B C A B 6~10 B B C B B 11~15 A B D (C,B) C 1.选择题 (1)串是一种特殊的线性表,其特殊性体现在(B) ...

  3. 《数据结构》-第四章 串、数组和广义表(习题)

    第四章 串.数组和广义表练习题 本章考点较少易于掌握,对于串的重点考点为串的模式匹配算法:数组的主要考点为数组下标与存储地址计算和特殊矩阵的压缩存储方法:针对广义表的考点主要为在广义表中取原子项(表) ...

  4. 数据结构c语言版第四章题库,严蔚敏《数据结构(c语言版)习题集》答案第四章 串...

    严蔚敏<数据结构(c语言版)习题集>答案第四章 串 第四章 串 4.10 void String_Reverse(Stringtype s,Stringtype &r)//求s的逆 ...

  5. 第四章 串(数据结构与算法)

    第四章 串[数据结构与算法] 配套资源下载 第4章串 4.1应用实例 4.2串及其运算 4.2.1串的基本概念 4.2.2 串的基本运算 4.3串的存储结构及实现 4.3.1 定长顺序串 4.3.2 ...

  6. C语言数据结构-第四章 串-电大同步进度

    第四章 串 字符串是计算机处理的最基本的非数值数据.字符串是一种特定的线性表,其特殊性就在于组成线性表的每个元素就是一个单字符. 本章给出: l         串的基本概念 l         串的 ...

  7. 王道408数据结构——第四章 串(KMP算法)

    一.串的定义和实现 字符串简称串,是由零个或多个字符组成的有限序列,一般记为S=′a1a2⋅⋅⋅an′S='a_1a_2···a_n'S=′a1​a2​⋅⋅⋅an′​,n称为串的长度. 串中任意多个连 ...

  8. (王道408考研数据结构)第四章串-第一节:串的定义和基本操作及存储结构

    文章目录 一:串基本概念 (1)串的定义 (2)相关术语 (3)串的基本操作 二:串的比较 三:字符集编码 四:串的存储结构 (1)串的顺序存储 (2)串的链式存储 一:串基本概念 (1)串的定义 串 ...

  9. 《数据结构》第四章串,数组和广义表

    <数据结构>第四章 文章目录 <数据结构>第四章 4.1 串的定义 4.2 案例引入 4.3 串的类型定义,存储结构及其运算 4.3.1 串的抽象类型定义 4.3.2的存储结构 ...

最新文章

  1. OpenCV java 图像基本处理-模糊 (8)
  2. 《深入理解java内存模型》学习整理1
  3. Autofac IoC容器基本使用步骤【1】
  4. python海龟漂亮图案代码大全_Python游戏海龟图案
  5. Package fontspec Error: The font “SimHei“ cannot be found. windows 上海交大学位论文模板
  6. Mybatis快速入门及遇到的问题(不支持发行版本)(黑马程序员Javaweb)
  7. Win7 32 不能安装STM32 虚拟串口驱动解决方法
  8. 送学计算机男生什么礼物好,【十大男生喜欢的礼物】男生渴望收到什么礼物_主妇网...
  9. 将esx虚拟机从一台服务器迁移,虚拟化应用支招:ESX VtoP迁移实战
  10. CF446C DZY Loves Fibonacci Numbers 万能的线段树
  11. 棋盘密码(Polybius)
  12. Kubernetes Pod Eviction 简介
  13. Android运用手机多媒体
  14. 【Delphi】中使用消息Messages(五)Windows消息
  15. win10 系统网络驱动出现黄色感叹号
  16. 基于百度paddlehub多种海洋鱼类的智能分类识别
  17. 关于setObjectName的思考
  18. java小程序_Java小程序
  19. 输出信噪比公式_如何计算信号的信噪比
  20. 2022年东南大学计算机考研复试分数线

热门文章

  1. JumpServer 安装部署
  2. 星戈瑞-脂溶性CY3-MAL的作用及注意事项
  3. 二分查找法。Java泛型设计二分查找法。
  4. 加密越来越简单——用JavaScript实现数据加密和解密
  5. EXTJS中整合tinymce的富文本编辑器,添加上传图片功能
  6. confluence安装配置详细过程(实践篇)
  7. Sql Server查询中生成流水号
  8. go mod 包的创建以及怎么组织项目目录
  9. Git(分布式版本管理工具)
  10. python day 14