第四章学习小结
一、本章内容小结
本章学习了串、数组和广义表。重点学习了串模式匹配的BF算法和KMP算法。BF算法简单直观,易于理解,但是并不能广泛应用,往往会出现运行超时的问题。KMP算法在理解上有一定的难度,其代码的逻辑性很强,学习的时候,侧重逻辑推理更能帮助理解。
1、串----包括顺序存储结构(定长顺序存储结构和堆式顺序存储结构)和链式存储结构。
1 //串的顺序存储结构--定长顺序存储结构和堆式顺序存储结构 2 //定长顺序存储结构 3 #define MAXLEN 255 //串的最大长度 4 typedef struct 5 { 6 char ch[MAXLEN+1]; 7 int length; 8 }SString; 9 10 //堆式顺序存储结构 11 typedef struct 12 { 13 char *ch; 14 int length; 15 }HString; 16 17 //串的链式存储结构/块链结构 18 #define CHUNKSIZE 80 //由用户定义的块大小 19 typedef struct Chunk 20 { 21 char ch[CHUNKSIZE]; 22 struct Chunk *next; 23 }Chunk; 24 typedef struct 25 { 26 Chunk *head, *tail; //串的头和尾指针 27 int length; 28 }LString;
BF算法----简单直观,但存在回溯,效率低,时间复杂度为O(m*n),并不能普遍适用。
1 int Index_BF(SString S, SString T, int pos} 2 { 3 i=pos; j=l; 4 while(i<=S.length && j<=T.length) 5 { 6 if(S[i].ch==T[j].ch) {++i; ++j;} 7 else {i=i-j+2; j=l;} 8 } 9 if(j>T.length) return i-T.length; 10 else return O; 11 }
KMP算法----有get_next函数的预先处理,消除回溯,提高了效率,时间复杂度为O(m+n),该算法应用较广。
1 int Index_KMP(SString S, SString T, int pos) 2 { 3 i=pos; j=1; 4 while(i<=S.length && j<=T.length) 5 { 6 if(S.ch[i]==T.ch[j]) 7 { i++; j++; } 8 else 9 { 10 j=next[j]; //i不变,j后退 11 if(j==0) 12 {//表示模式第一个字符就比较失败 13 i++; j++; 14 } 15 } 16 } 17 if(j>T.length) return i-T.length; 18 else return 0; 19 } 20 void get_next(SString T, int next[]) 21 { 22 j=1; next[1]=0; k=0; 23 while(j<T.length) 24 { 25 if(k==0||T.ch[j]==T.ch[k] 26 { 27 ++j; ++k; 28 next[j]=k; 29 } 30 else 31 { k=next[k]; } 32 } 33 }
2、数组----是一种随机存储结构
除了结构的初始化和销毁之外,数组只有存取元素和修改元素值的操作。由于数组一般不做插入或删除操作,因此顺序存储结构表示数组比较合适。矩阵是数组的一种类型,而特殊矩阵(对称矩阵、三角矩阵、对角矩阵和稀疏矩阵)的压缩存储能有效减少存储空间。
3、广义表
广义表是线性表的推广,也称列表。广义表不一定是线性表,也不一定是线性结构。线性表是一种特殊的广义表。广义表通常采用链式存储结构:头尾链表的存储结构和扩展线性链表的存储结构。
二、作业的编程题用BF算法不能有效解决问题,只能用KMP算法。刚开始总会出现首字符或尾字符不匹配,但是代码自动将他们匹配的问题,导致有几个测试点答案错误或段错误,后来询问同学,修改之后,才正确了。实践题求集合的交集,刚开始尝试总出现运行超时,搜索一番以后,明白需要先对数组排序在求交集,sort函数包含在algorithm文件中,有尝试过自己编写sort函数,但是其时间复杂度似乎总没有文件自带的低。
三、博客园是一个很好的学习空间,当存在疑惑时,搜索一番,总能发现已有前人遇到相同的问题,并提出了有效的解决方案,可供我们更好地学习。
四、五一拖拖拉拉,也终于在最后的一两天完成了所有作业。不能轻易落下现有的功课,以前的知识点可以在现下的学习穿插回顾。接下来还是好好打代码,注重理解,逻辑也得更上。