第四章主要是串和数组的学习,之前对串和数组的应用仅限于对其单独处理,本章学习着重于对具体题目的实际操作,实践了串的模式匹配算法,对其有了更深入的了解,数组的应用拓展到了稀疏矩阵的存储的实现。
一.串
串的模式匹配
BF算法
首先未匹配到串尾时,将两个字符串一一匹配,可用C++自带的length()函数实现
while(i<=S.length()&&j<=T.length())
接下来就是匹配的过程
if(S[i]==T[j]){ i++;j++; }//若匹配则继续比较下一位 else{ pos++; i=pos; j=0; }//若不匹配则i回溯到之前比较的首位的下一位,j回溯到首位
BF算法简单粗暴容易理解,但最坏情况下时间复杂度高,使用改进算法KMP算法j不必回溯,减少了时间复杂度。
二.数组:
数组是一种随机存取结构,使用数组存储的数据,可以通过其规律性,由下标计算其存储位置
C(i)= L(i=n)
C(i)=C(i+1)*b(i+1)
用二维数组可以表示一些特殊矩阵,如对称矩阵、三角矩阵、对角矩阵及稀疏矩阵,本章着重于实现用二维数组存储稀疏矩阵的方法。
稀疏矩阵
在稀疏矩阵中,我们要做的就是存储非0元素的信息,首先单独思考一个非0元素,我们要存储的是它的行号、列号、值,可以用一个三元组实现。
typedef struct{//定义一个三元组存放稀疏矩阵中非0元素的信息 int i; int j; int value; }node;
再将眼光放远到整个矩阵中,我们要存储的信息的是矩阵的行数、列数、非0元素的个数和信息,于是我们在矩阵的类中嵌套进三元组类。
typedef struct{//存放矩阵信息 int m;//矩阵行数 int n;//矩阵列数 int N;//非0元素的个数 node a[500];//非0元素信息 }Matrix;
接下来就是输入输出啦
三、AI核心代码
该题目的具体要求主要是:1.删除多余空格 2.大写转小写 3.I,me换成you 4.?换! 5.can you换I can,了解具体要求后,我们就可以先开始写主函数形成大体解题框架,再通过具体函数的编写实现程序。
解题过程中有几个比较重要的点:
1. 平时对字符扫描时一般用习惯for,但具体用for还是while还是要根据条件来判断,有规律逐个扫描用for,无规律用while。在该题中,我们需要有规律地逐个扫描字符,于是用for语句定位到第一个非空字符串。
for(i=0;s[i]!='\0'&&s[i]==' ';i++);
2. 在实现大写转小写时编写代码比较复杂,而像这样操作一般都会有函数可以直接调用,平时可以多积累一些函数需要用到时直接调用,如该题可以直接调用tolower函数程序会简洁许多
if(s[i]!='I'){ t[j]=tolower(s[i]);//大写转小写 ++j,++i; continue; } else t[j++]=s[i++];
3. 题目中要求被转化的词是独立的,我们可以编写一个函数确保被转化的词的独立性,通过判断是否前后是否为分隔符来判断,而分隔符种类很多不能一一列举,于是我们可以往相反方向思考,除了字母和数字之外都是分隔符
bool independent(char ch){//判断是否为分隔符(除字母和数字) ch=tolower(ch); if(ch>='0'&&ch<='9'||ch>='a'&&ch<='z') return false; else return true; }
分隔符问题要考虑溢出,当字符前面没有分隔符即i=0时该字符头部也是独立的
j==0||independent(t[j-1])
该语句可以解决这个问题,当||前面条件成立时不判断后面条件是否成立,直接判断为字符前无分隔符,头部独立。
再做相似题目时,先写出大体框架,再一步步完善未考虑到的溢出及边界问题
四、总结
KMP算法还是没能研究出来怎么写,希望之后能一点点消化它的思想。虽然写出了AI核心代码的题目,但大部分还是在老师带领下写的,希望之后能自主写出这样一段神奇有趣的代码。