DS第4章学习小结

  1. 你对本章内容的小结
  2. 完成作业或实践时解决困难的经验分享
  3. 这段时间,你参考了哪些值得向大家分享的资料?每一项推荐都请说明推荐理由及列出相关链接(或书目名称,具体页码)
  4. 目前学习过程中存在的困难,待解决或待改进的问题
  5. 上次博客确定的目标达到了吗?如果没达到,请分析原因
  6. 接下来的目标

一、你对本章内容的小结

  第4章主要学习了  串  和  数组

  主要学习了有关  模式匹配算法  的两种算法:T(n)=O(m*n)的BF算法  和  T(n)=O(m+n)的KMP算法

  KMP算法难在求出  模式的next数组。(即求next数组时的思想)

  

  数组主要学习了  怎么求具体下标的元素的地址  以及  如何用一维数组将一些特殊矩阵(如对称矩阵、三角矩阵、对角矩阵、稀疏矩阵等)进行压缩存储。

二、完成作业或实践时解决困难的经验分享

  先上修正前的代码:

 1 #include<iostream>
 2 using namespace std;
 3 
 4 
 5 void getnext(string t, int *next);
 6 int match(string S, string T, const int *next);
 7 
 8 
 9 int main()//7-1 串的模式匹配
10 {
11 //    freopen("input.txt","r",stdin);
12 //    freopen("output.txt","w",stdout);
13 
14 
15     string S;
16     string T;
17     cin>>S;
18     cin>>T;
19     
20 
21     int next[T.length()];
22     getnext(T,next);
23     
24     
25     cout<<match(S,T,next);
26     
27 
28 return 0;
29 }
30 
31 
32 
33 
34 void getnext(string t, int *next)
35 {
36     next[0]=-1;
37     for(int i=0,j=-1; i<t.length();)
38     {
39         if(j==-1||t[i]==t[j])
40         {
41             i++;j++;
42             next[i]=j;
43         }
44         else    j=next[j];
45     }
46 }
47 
48 
49 int match(string S, string T, const int *next)
50 {
51     int i=0,j=0;
52     for(;i<S.length()&&j<T.length();)
53     {
54         if(j==-1||S[i]==T[j])
55         {
56             i++;j++;
57         }
58         else
59         {
60             j=next[j];
61         }
62     }
63     if(j==T.length())    return    i-T.length()+1;
64     else    return 0;        
65 }
View Code

  这是我最开始做PTA第4章作业的串的模式匹配的时候用KMP算法写的代码,

  这是个有点错的代码。

 

  修正后的代码:

 1 #include<iostream>
 2 using namespace std;
 3 
 4 
 5 void getnext(string t, int *next);
 6 int match(string S, string T, const int *next);
 7 
 8 
 9 int main()//7-1 串的模式匹配
10 {
11 //    freopen("input.txt","r",stdin);
12 //    freopen("output.txt","w",stdout);
13 
14 
15     string S;
16     string T;
17     cin>>S;
18     cin>>T;
19     
20 
21     int next[T.length()];
22     getnext(T,next);
23     
24     
25     cout<<match(S,T,next);
26 
27 
28 return 0;
29 }
30 
31 
32 
33 
34 void getnext(string t, int *next)
35 {
36     next[0]=-1;
37     for(int i=0,j=-1; i<(int)t.length();)
38     {
39         if(j==-1||t[i]==t[j])
40         {
41             i++;j++;
42             next[i]=j;
43         }
44         else    j=next[j];
45     }
46 }
47 
48 
49 int match(string S, string T, const int *next)
50 {
51     int i=0,j=0;
52     for(;i<(int)S.length()&&j<(int)T.length();)
53     {
54         if(j==-1||S[i]==T[j])
55         {
56             i++;j++;
57         }
58         else
59         {
60             j=next[j];
61         }
62     }
63     if(j==(int)T.length())    return    i-T.length()+1;
64     else    return 0;        
65 }
View Code

  这是我修改过后的代码,可以看到我只是在  字符串的长度  前加了(int)进行类型转换,简单来说,就是

  负数  不能与  字符数组的strlen(s)  以及  字符串的s.length  进行比较,

  或者说  有符号整型中的负数  不能与  无符号整型  进行比较。

 

  1 #include<iostream>
  2 #include<string.h>
  3 using namespace std;
  4 
  5 
  6 const int MAXSIZE=1002;
  7 
  8 
  9 void change2(char *ch);//空格 
 10 void change3(char *ch);//大写变小写 
 11 void change4_6(char *ch);//I和me变成you以及can you变成I can
 12 void change5(char *ch);//?变成!
 13 bool punctuation(char ch);//判断标点符号 
 14 
 15 
 16 int main()//7-2 AI核心代码
 17 {
 18 //    freopen("input.txt","r",stdin);
 19 //    freopen("output.txt","w",stdout);
 20     int n=0;
 21     cin>>n;
 22     cin.ignore(10,'\n');
 23     
 24     
 25     char a[n][4*MAXSIZE];
 26     
 27     
 28     for(int i=0; i<n; i++)
 29     {
 30         cin.getline(a[i],MAXSIZE);
 31     }
 32 
 33 
 34     for(int i=0; i<n; i++)
 35     {
 36         cout<<a[i]<<endl;
 37         cout<<"AI: ";
 38 
 39 
 40         change2(a[i]);
 41         change3(a[i]);
 42         change4_6(a[i]);
 43         change5(a[i]);
 44         
 45         
 46         cout<<a[i];
 47 
 48 
 49         if(i!=n-1)
 50         cout<<endl;
 51     }
 52 
 53 
 54 return 0;    
 55 } 
 56 
 57 
 58 
 59 
 60 void change2(char *ch)//空格 
 61 {
 62     int k=0;
 63     for(int i=0; ch[i]!='\0'; i++)//前空格 
 64     {
 65         if(ch[i]==' ')
 66         k++;
 67         else    break;
 68     }
 69     for(int i=k,j=0; ch[i]!='\0'; i++,j++)
 70     {
 71         ch[j]=ch[i];
 72     }
 73     ch[strlen(ch)-k]='\0';
 74     
 75     
 76 /*  for(int i=0,j=0; ch[i]!='\0'; i++)//中空格 
 77     {
 78         if(ch[i]!=' '||ch[i-1]!=' ')
 79         {
 80             ch[j]=ch[i];
 81             j++;
 82             k=j;
 83         }
 84     }
 85     ch[k]='\0';*/
 86 
 87 
 88     for(int i=0,j=0; ch[i]!='\0'; i++)//中和后空格 
 89     {
 90         if(ch[i]!=' '||!punctuation(ch[i+1]))
 91         {
 92             ch[j]=ch[i];
 93             j++;
 94             k=j;
 95         }
 96     }
 97     ch[k]='\0';
 98     
 99     
100 /*  if(ch[strlen(ch)-1]==' ')    ch[strlen(ch)-1]='\0';//后空格*/
101 }
102 
103 
104 void change3(char *ch)//大写变小写  
105 {
106     for(int i=0; ch[i]!='\0'; i++)
107     {
108         if('A'<=ch[i]&&ch[i]<='Z'&&ch[i]!='I')
109         ch[i]=ch[i]+32;
110     }
111 }
112 
113 
114 void change4_6(char *ch)//can you变成I can    以及    I和me变成you
115 {
116     char m[4*strlen(ch)];
117     int k=0;
118     for(int i=0,j=0; ch[i]!='\0';)
119     {
120         if((strlen(ch)-i)>=7&&(i==0||punctuation(ch[i-1]))&&ch[i]=='c'&&ch[i+1]=='a'&&ch[i+2]=='n'&&ch[i+3]==' '&&ch[i+4]=='y'&&ch[i+5]=='o'&&ch[i+6]=='u'&&punctuation(ch[i+7]))
121         {
122             m[j]='I';m[j+1]=' ';m[j+2]='c';m[j+3]='a';m[j+4]='n';
123             i=i+7;j=j+5;
124             k=j;
125         }
126         else if((i==0||punctuation(ch[i-1]))&&ch[i]=='I'&&punctuation(ch[i+1]))
127         {
128             m[j]='y';m[j+1]='o';m[j+2]='u';
129             i++;j=j+3;
130             k=j;
131         }
132         else if((i==0||punctuation(ch[i-1]))&&ch[i]=='m'&&ch[i+1]=='e'&&punctuation(ch[i+2]))
133         {
134             m[j]='y';m[j+1]='o';m[j+2]='u';
135             i=i+2;j=j+3;
136             k=j;            
137         }
138         else
139         {
140             m[j]=ch[i];
141             i++;j++;
142             k=j;
143         }
144     }
145     
146     
147     for(int i=0; i<k; i++)
148     {
149         ch[i]=m[i];
150     }
151     ch[k]='\0';
152 }
153 
154 
155 void change5(char *ch)//?变成! 
156 {
157     for(int i=0; ch[i]!='\0'; i++)
158     {
159         if(ch[i]=='?')    ch[i]='!';
160     }
161 }
162 
163 
164 bool punctuation(char ch)//判断标点符号 
165 {
166     return (!('0'<=ch&&ch<='9')&&!('A'<=ch&&ch<='Z')&&!('a'<=ch&&ch<='z'));
167 }
View Code

  这是我做PTA第4章实践1的AI核心代码的时候写的代码,我的想法是一次性输入所有的对话,然后根据要求对输入的对话进行修改,再输出对话。

  需要注意的是,

  因为题目中  “把原文中所有独立的 I 和 me 换成 you;”  的这个要求会加长字符串的长度,所以要预先给对话的字符数组分配更大的空间。

  在实现  “把原文中所有独立的 can you 换成 I can;”  和  “把原文中所有独立的 I 和 me 换成 you;”  的时候,应先实现前者,再实现后者。

  然后,因为修改时对话的长度有可能会不停的变,所以要在合适的地方加上结束符'\0'  如ch[k]='\0';,

  其他的根据题目的要求去写代码就好。

三、这段时间,你参考了哪些值得向大家分享的资料?每一项推荐都请说明推荐理由及列出相关链接(或书目名称,具体页码)

  https://www.cnblogs.com/chenxiwenruo/p/3546457.html

  这是一个有关KMP算法的博客,里面说到了,

  “理解next数组的含义:next[i]表示前面长度为i的子串中,前缀和后缀相等的最大长度”。

  若按此博客中的理解去想,则  next[i]既是下标、又是最大长度,

  而按书中的描述去想,则  next[i]只为位置,

  对我来说,前者更容易使人接受、理解。

四、目前学习过程中存在的困难,待解决或待改进的问题

  脑子还是太缺筋,将很多简单的问题复杂化了。

  还有就是我觉得我对i和j有执念,我觉得i和j的作用域一定要在循环里面/捂脸,导致如果要在循环外用到i或j结束时的值时,我会引入一个k在循环中记录i或j的值。

五、上次博客确定的目标达到了吗?如果没达到,请分析原因

  没达到,没有看老师给的高质量c++编程指南31~60页,因为自己做事的效率实在太低,整天都在空思考,重复思考。

六、接下来的目标

  看老师给的高质量c++编程指南31~90页。

  

 

posted on 2019-04-14 15:14  J丶2000  阅读(173)  评论(2编辑  收藏  举报

导航