第4章小结
第4章主要学习内容:
BF算法最坏情况下的平均时间复杂度:O(n×m)
KMP算法:O(n+m)
1.模式匹配
做这道题的时候直接用BF算法没有什么困难,就是要注意pos是取下标还是取位置,一开始没有注意到这个点所以在最后的返回值那里有错。用BF算法顺利地通过了前几个测试点,但是在最后一个测试点显示运行超时,但是KMP算法我还没有摸透,课上讲的内容也没能很好的消化也没有完全理解,所以没有用KMP算法尝试。
pos取位置时
1 while(i <= s.length && j <= t.length) 2 { 3 if (s.ch[i]==t.ch[j]) {++i; ++j;} 4 else{i=i-j+2; j=1;} //s退回至原来的后一位置,j回到第一个 5 }
pos取下标时
1 while(i <= s.length && j <= t.length) 2 { 3 if (s.ch[i]==t.ch[j]) {++i; ++j;} 4 else{i=i-j+1; j=0;} //s退回至原来的后一位置,下标+1,j回到下标0 5 }
2.稀疏矩阵
做这道题的时候我一开始想的是用类似数组的结构来存储,课上老师介绍了三元组表和十字链表,课后我用三元组表完善了自己的代码。一开始在处理查找不到k时输出ERROR时我想用if条件来判断,但是一直不知道要怎么判断条件,后来想到在找到k后做标记t=1,t不等于1就输出ERROR,问过同学后了解到也可以用if判断:当最后一个元素不等于k时就输出ERROR((t.a[i].value != k) && (i == t.length-1))。
以下是完整代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 using namespace std; 3 typedef struct 4 { 5 int i; 6 int j; 7 int value; 8 }node;//三元组表 9 typedef struct 10 { 11 node a[500]; 12 int length; 13 }S;//三元组表和长度打包 14 int main() 15 { 16 S b; 17 int m,n,N,k,p,t=0; 18 cin>>m>>n>>N; 19 b.length=N; 20 for(p=0;p<b.length;p++) 21 {//输入非零元素 22 cin>>b.a[p].i>>b.a[p].j>>b.a[p].value; 23 } 24 cin>>k;//输入要查询的数k 25 for(p=0;p<b.length;p++) 26 {//查找该非零元素 27 if(k==b.a[p].value) 28 { 29 cout<<b.a[p].i<<' '<<b.a[p].j<<endl; 30 t=1;//标记是否查找到该非零元素 31 break; 32 } 33 } 34 if(t!=1)//未查找到则输出ERROR 35 cout<<"ERROR"<<endl; 36 return 0; 37 }
3.AI核心代码
这个在课上跟着老师的讲解打代码没有什么太大的困难,主要学到了要学会划分层次,保证主函数清晰,课上只讲到判断单独的I和me,can you也是类似的判断方法,所以在写的时候也比较顺利。一开始我没有加getchar()函数,所以导致回车符不能吸收所以后面的输入也有问题,加上getchar()之后马上就成功了。我也搜了一下getchar()函数用法:getchar由宏实现:#define getchar() getc(stdin)。getchar有一个int型的返回值。当程序调用getchar时.程序就等着用户按键。用户输入的字符被存放在键盘缓冲区中。直到用户按回车为止(回车字符也放在缓冲区中)。当用户键入回车之后,getchar才开始从stdio流中每次读入一个字符。
一开始我定义字符串t为string类型,一直无法输出,后来就改成了字符数组,后来看了老师的博客才指导要写成cout<<t.data()<<endl;
以下是完整代码
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 using namespace std; 3 #include <string> 4 #include <cstring> 5 #include <cstdio> 6 #include <stdio.h> 7 8 void go(string s); 9 bool isAlone(char); 10 11 int main() 12 { 13 int n;//行数n 14 string s;//存放输入语句 15 cin>>n; 16 getchar(); 17 for(int i=0;i<n;i++) 18 { 19 getline(cin,s); 20 cout<<s<<endl; 21 cout<<"AI: "; 22 go(s);//处理并输出回答 23 } 24 return 0; 25 } 26 void go(string s) 27 { 28 int i,j=0; 29 char t[1000];//用于存放处理后的字符 30 for(i=0;s[i]!='\0'&&s[i]==' ';i++) ;//定位到第一个非空格字符 31 while(s[i]!='\0') 32 { 33 if(s[i]==' '&&s[i-1]==' ') 34 {//跳过连续空格 35 i++; 36 continue; 37 } 38 if(s[i]=='?') 39 {//将?换成! 40 t[j]='!'; 41 i++; 42 j++; 43 continue; 44 } 45 if(s[i]!='I') 46 {//除I以外大写变小写 47 t[j]=tolower(s[i]); 48 i++; 49 j++; 50 } 51 else 52 { 53 t[j]=s[i];//将s的非空和单个空格赋给t 54 j++; 55 i++; 56 } 57 }//while 58 t[j]='\0'; 59 if(t[j-1]==' ')//将t串的句末的空格变成结尾符 60 t[j-1]='\0'; 61 62 j=0; 63 while(t[j]!='\0') 64 { 65 if(t[j]=='I'&&(j==0||isAlone(t[j-1]))&&isAlone(t[j+1])) 66 {//独立的I变成you 67 cout<<"you"; 68 j++; 69 continue; 70 } 71 if(t[j]=='m'&&t[j+1]=='e'&&(j==0||isAlone(t[j-1]))&&isAlone(t[j+2])) 72 {//独立的me变成you 73 cout<<"you"; 74 j+=2; 75 continue; 76 } 77 if((t[j]=='c'&&t[j+1]=='a'&&t[j+2]=='n'&&t[j+3]==' '&&t[j+4]=='y'&&t[j+5]=='o'&&t[j+6]=='u')&&(j==0||(isAlone(t[j-1])&&isAlone(t[j+7])))) 78 {//独立的can you 79 cout<<"I can"; 80 j+=7; 81 continue; 82 } 83 if(t[j]==' '&&isAlone(t[j+1])) 84 {//标点前的空格不输出 85 j++; 86 continue; 87 } 88 cout<<t[j]; 89 j++; 90 } 91 cout<<endl; 92 } 93 94 bool isAlone(char s) 95 {//判断是否独立 96 s=tolower(s); 97 if((s>='0'&&s<='9')||(s>='a'&&s<='z')) 98 return false; 99 else 100 return true; 101 }
通过这一章的三道编程题我觉得还是收获蛮多的,虽然AI是跟着老师做,而且也参考了老师的代码,但是通过自己研究努力看懂代码也有一定收获,而且也补充了额外知识。
目标:希望自己可以努力钻研一下KMP算法尝试一下,看看十字链表要怎么实现,习惯多写接口函数,多问多思考!:D