本章学习了三种数据结构:串、数组和广义表。而作业其中的“稀疏矩阵”这题用到了三维数组的知识,“串的模式匹配”这题用到了串的KMP算法,“AI核心代码”这题则涉及比较多与串相关的知识。
周四上机实验的时候,老师带着我们从头到尾梳理了一遍做题思路,首先要考虑数据结构(字符串/字符数组)。一开始没有考虑周全,选用了字符串,但没有对其初始化,为其分配地址,导致后来赋值的时候没有分配一个首地址,输出就会使得程序出错。由于解决这个问题比较复杂(要在初始化的时候输入所有字符或者用for循环遍历),因此改用字符数组的方式。
然后根据题目要求,分别写好不同功能的函数。
- 判断ch是否分隔字符的函数
1 bool isIndependent(char ch){//判断ch是否分隔字符(字母、数字、空格、标点、\0) 2 ch=tolower(ch); 3 if(ch>='0'&&ch<='9'||ch>='a'&&ch<='z') 4 return false; 5 else 6 return true; 7 }
- 判断是否为独立的can you的函数
1 bool isCanyou(char ch[],int n){//判断是否为独立的can you 2 if (ch[n]=='c'&&ch[n+1]=='a'&&ch[n+2]=='n'&&ch[n+3]==' '&&ch[n+4]=='y'&&ch[n+5]=='o'&&ch[n + 6]=='u'){ 3 if((n==0||isIndependent(ch[n-1]))&&isIndependent(ch[n+7])) 4 return true; 5 } 6 return false; 7 }
- 根据s输出AI的回答的函数
1 void go(string s){//根据s输出AI的回答 2 char t[3001]; 3 int i,j;//i:定位到s的第一个非空 4 for(i=0;s[i]!='\0'&&s[i]==' ';++i); 5 j=0; 6 while(s[i]!='\0'){//把s串copy到t,连续空格只copy一个 7 if(s[i]==' '&&s[i-1]==' '){ 8 ++i; 9 continue; 10 } 11 if(s[i]=='?'){ 12 t[j++]='!'; 13 ++i; 14 continue; 15 } 16 if(s[i]!='I'){ 17 t[j]=tolower(s[i]); 18 ++j,++i; 19 continue; 20 } 21 t[j++]=s[i++]; 22 } 23 t[j]='\0'; 24 j=0; 25 while(t[j]!='\0'){ 26 if(t[j]=='I'&& (j==0||isIndependent(t[j-1]))&&isIndependent(t[j+1])){ 27 cout<<"you"; 28 ++j; 29 continue; 30 } 31 if(t[j]=='m'&&t[j+1]=='e'&&(j==0||isIndependent(t[j-1]))&&isIndependent(t[j+2])){ 32 cout<<"you"; 33 j=j+2; 34 continue; 35 } 36 if(t[j]==' '&&isIndependent(t[j+1])){ 37 ++j; 38 continue; 39 } 40 if(isCanyou(t,j)){ 41 cout<<"I can"; 42 j=j+7; 43 continue; 44 } 45 cout<<t[j]; 46 ++j; 47 } 48 cout<<endl; 49 }
最后写上主函数,调用上面所写的函数,整个程序就写好了。
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <string> 5 using namespace std; 6 bool isIndependent(char ch){//判断ch是否分隔字符(字母、数字、空格、标点、\0) 7 ch=tolower(ch); 8 if(ch>='0'&&ch<='9'||ch>='a'&&ch<='z') 9 return false; 10 else 11 return true; 12 } 13 14 bool isCanyou(char ch[],int n){//判断是否为独立的can you 15 if (ch[n]=='c'&&ch[n+1]=='a'&&ch[n+2]=='n'&&ch[n+3]==' '&&ch[n+4]=='y'&&ch[n+5]=='o'&&ch[n + 6]=='u'){ 16 if((n==0||isIndependent(ch[n-1]))&&isIndependent(ch[n+7])) 17 return true; 18 } 19 return false; 20 } 21 22 void go(string s){//根据s输出AI的回答 23 char t[3001]; 24 int i,j;//i:定位到s的第一个非空 25 for(i=0;s[i]!='\0'&&s[i]==' ';++i); 26 j=0; 27 while(s[i]!='\0'){//把s串copy到t,连续空格只copy一个 28 if(s[i]==' '&&s[i-1]==' '){ 29 ++i; 30 continue; 31 } 32 if(s[i]=='?'){ 33 t[j++]='!'; 34 ++i; 35 continue; 36 } 37 if(s[i]!='I'){ 38 t[j]=tolower(s[i]); 39 ++j,++i; 40 continue; 41 } 42 t[j++]=s[i++]; 43 } 44 t[j]='\0'; 45 j=0; 46 while(t[j]!='\0'){ 47 if(t[j]=='I'&& (j==0||isIndependent(t[j-1]))&&isIndependent(t[j+1])){ 48 cout<<"you"; 49 ++j; 50 continue; 51 } 52 if(t[j]=='m'&&t[j+1]=='e'&&(j==0||isIndependent(t[j-1]))&&isIndependent(t[j+2])){ 53 cout<<"you"; 54 j=j+2; 55 continue; 56 } 57 if(t[j]==' '&&isIndependent(t[j+1])){ 58 ++j; 59 continue; 60 } 61 if(isCanyou(t,j)){ 62 cout<<"I can"; 63 j=j+7; 64 continue; 65 } 66 cout<<t[j]; 67 ++j; 68 } 69 cout<<endl; 70 } 71 72 int main(){ 73 int n; 74 string s; 75 cin>>n; 76 getchar();//吸收回车 77 for(int i=1;i<=n;i++){ 78 getline(cin,s); 79 cout << s << endl; 80 cout<<"AI: "; 81 go(s);//根据s输出AI的回答 82 } 83 return 0; 84 }
其中还要注意的是,字符数组最后的结尾符“\0”会占用一个空间;当写到j+1、j-1的时候,要考虑边界情况,如果I,me在开头,那么j-1就会越界是的程序出错;另外在做这道题的时候,有一个语句由于粗心把“==”打成了“=”导致程序出错,检查了很久也没看出来,浪费了不少时间,因此以后打代码的时候一定要全神贯注,注意规范。
本周除了学习课堂上的知识外,自己也上网看了有关本章的博客和一些解题思路,希望在往后的学习中,在学好课堂知识点的同时,也多看看课外相关的内容,多练练题目,从而提升自己的编程能力。