第四章学习小结 串,数组,和广义表

一,本章学习内容有:

1,串的类型定义,存储结构及其运算

记录的一些知识点:

(1)C语言,求串的长度

char a[100];

strlen();

(头文件为<string.h>

而C++中

string a;

a.length();

(2)串的模式匹配算法

对比 BF算法和KMP算法

难点:KMP算法中的next[ ]函数

作业题的第一题可以应用这两种方法来解题

但是由于next函数的一些问题还没解决,所以我的代码只是部分正确

 1 #include <iostream>
 2 #include <string.h>
 3 using namespace std;
 4   
 5   //计算next函数
 6   int* get_next(string T)//通过相等的两条模式串得出next的规律 
 7   {
 8       int* next = new int[T.length()];//为next数组动态 分配空间 
 9       int i = 1;
10     next[1] = 0; 
11     int j = 0;
12       while(i<T.length())//未到达队尾
13       {
14           if(j == 0 || T[i] == T[j])//如果j为0 或者 两个对应字符相等 
15           {++i;++j;next[i]=j;}//后移一位,把j的位置记到next函数中 
16           else j = next[j];//否则,下面的模式根据next函数右移 
17        } 
18        return next;//因为是指针函数,所以返回next数组首地址 
19   }
20 
21  //KMP算法
22  int Index_KMP(string S,string T)
23  {
24     int j = 1;
25     int i = 1; //位置? 
26     int m = S.length();
27     int n = T.length(); 
28     int *next=get_next(T);//用next指针接受指针函数传来的数组地址  
29 
30      while(i<=m && j<=n)//l两串均未到达队尾
31      {
32      if(j==0 || S[i] == T[i])
33      { ++i;++j; }//若模式串为0 或 两对应字符相等,后移一位 
34      else j = next[j];//若不匹配且j不为0,则模式串右移,通过next[]函数 
35      if(j>n) return i-n;//若匹配,则j=j+1,会比模式串大1 
36      else return 0; }
37   } 
38   int main()
39   {
40       string S, T;
41       getline(cin,S);
42       getline(cin,T);
43       get_next(T);
44       cout << Index_KMP(S,T);
45       return 0;
46   }
作业题(KMP算法)

还有一个没解决的问题,不知道i,j表示的是下标还是位置,以及用下标或是位置的话,在代码中有什么不能解决的地方。

 

2,数组:

特殊矩阵中的对称矩阵,稀疏矩阵

因为课本中没有例题,PPT中关于这部分的代码也很少,所以在做实践题的第一题的时候有点不知道怎么下手,

参考了一些同学的博客后才有了一点想法,但是对于利用三元组表压缩和用十字链表压缩的实现,虽然知道想法,但我不知道怎么打这个代码。

 1 #include<iostream>
 2 using namespace std;
 3 typedef struct{
 4     int q;
 5     int p;
 6     int val;
 7 }node;
 8 typedef struct{
 9     int m, n, N;
10     node a[100];
11 }Matrix;
12 
13 int main()
14 {
15     Matrix K;
16     node a[100];
17     int P;
18     int m, n, N;
19     cin >> K.m;
20     cin >> K.n;
21     cin >> K.N;//输入矩阵的行数,列数,非0个数N,N可在下面用作输入的限制 
22     for(int i=0; i<K.N; i++){//输入每个元素的行,列,值到数组里 
23         cin >> K.a[i].q;
24         cin >> K.a[i].p;
25         cin >> K.a[i].val;
26     }
27     cin >> P;//输入待匹配的值P 
28     int i = 0;
29     int flag = 0;//设定标志
30     while(i < K.N) {
31         if(P == K.a[i].val){//对比看是否相等 
32         cout << K.a[i].q << ' ' <<K.a[i].p << endl;//如果相等,则输出该元素的行,列 
33         flag = 1;//修改标志值 
34         }
35         ++i;
36     }
37     if(flag == 0)
38     cout << "ERROR" <<endl;
39     return 0;
40 }
实践题第一题—稀疏矩阵

 

3,本周老师带着我们一起打了一道关于AI的题,感觉学到的东西很多,并且根据上课的代码,也能自己推出由“can you"换为”I can"的方法

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <string>//用string 的头文件 
  5 using namespace std;
  6 
  7  bool isDependent(char ch)
  8  {
  9      //判断ch是否分隔符
 10      //字母数字空格标点杠铃
 11      ch = tolower(ch);
 12      if((ch>='0'&&ch<='9')||(ch>='a'&&ch<='z'))
 13      return false;
 14      else
 15      return true; 
 16  }
 17  
 18  
 19  void go(string s){
 20      //根据S输出AI的回答
 21      char t[3001];
 22      //     1234  789
 23      //1234 789
 24      int i,j;//i为输入串的下标,j为输出串的下标 
 25      for(i=0;s[i]!='\0' && s[i]==' ';++i);//\0  当i定位到S的第一个非空,跳出循环 
 26      j = 0;
 27      
 28      
 29      //下面搞空格问题 
 30      while(s[i]!= '\0'){//i变化不规律,用while 不用if(i++)//把s串copy到t,连续空格只copy一个 
 31      
 32      if(s[i]==' ' && s[i-1]==' '){//空格前还是空格时,i加1跳过该空格 
 33          ++i;
 34          continue;} 
 35      
 36      if(s[i]=='?'){//当为问号时,改问号为感叹号 ,并下标都加一 
 37          t[j++] = '!';
 38          i++; 
 39          continue;//回到循环开头 ,回到判断是s[i]是否为结尾符 
 40      }
 41     
 42     if(s[i]!='I'){//除I以外的大写转小写 
 43     t[j]= tolower(s[i]);
 44     ++j,++i;
 45     continue;//回到循环开头 ,回到判断是s[i]是否为结尾符
 46   }
 47      t[j++] = s[i++];//因为前面的函数都有continue,进入了就退出,不读此句,所以该语句是用于第一句的空格处理
 48             //如果是非空字符后第一个空格,就写入t,然后i++,j++ 
 49              //不能copy连续的空格 ,先读变量值,为下一轮循环做准备 
 50         //此时t没有处理'\0' 后面读出字符串会出错  
 51 }
 52 
 53      t[j]='\0';// 字符串结尾标志;完全读完后,因为前面的while语句读不到、0,需要手动在t字符结尾附上\0 
 54 //s完全读入了t 
 55     j=0;//开始全部输出t并进行修改 
 56     while(t[j]!='\0'){
 57         if(t[j]=='I'&&(j==0||isDependent(t[j-1])&&isDependent(t[j+1])))//有j+1-1要考虑是否越界 
 58     {
 59         cout<<"you";
 60         ++j;
 61         continue;
 62     }
 63     //下面搞me,考虑独立和不独立 
 64     if(t[j]=='m' && t[j+1]=='e' && (j==0||isDependent(t[j-1])&&isDependent(t[j+2])))//j+2不会越界,因为与的特性,前面的对了就不看后面的 
 65     {
 66     cout<<"you"; 
 67     j=j+2;
 68     continue;
 69     }
 70     
 71     if(t[j]==' ' && isDependent(t[j+1])){
 72         ++j;
 73         continue;
 74     }
 75 
 76     //搞canyou
 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' && isDependent(t[j-1])&&isDependent(t[j+7]))//can you待搞
 78 {
 79     cout << "I can";
 80     j = j+7;
 81     continue;
 82     }
 83      
 84     cout << t[j]; //如果不是上述情况,不用修改,直接输出 
 85    ++j;//这种情况不会自动加1, 
 86   }  
 87   //t串全部输出 
 88   cout << endl;//输出空行 
 89 }
 90  
 91 
 92 int main()
 93 {
 94     int n;
 95     string s;
 96     cin >> n;
 97     getchar();//吸收回车,头文件<cstdio> 
 98     for(int i=1; i<=n; i++){
 99         //读一个字符串
100         getline(cin,s);//与string s,对应 
101         cout<<s<<endl;
102         cout<<"AI: ";
103         go(s);
104     }
105     
106  }
AI

但回来之后发现有一些细节没处理好

比如说(1)括号的范围很乱,

(2)不知道为什么要用这些头文件

 

最后,进行本周学习小结:

(1)上周的目标实现了吗?

这周打代码的时间较多,特别是周四实践课之后,对那道题非常地想弄明白,但是由于我上学期C++学的不是很好,很多地方不知道要这样写就不行,要纠结很久,比如单引号和双引号的区别,参数里面有的未知数,在主函数中是否还要重新定义一遍等等。

但是因为这周题有点难,纠结的时间更久,有些地方还没有纠结出来,希望下周可以解决掉这些问题。

(2)本周做题不足和收获

a)比如说括号很乱的问题,我发现,只要标清楚了注释,很容易就可以找出是哪里少了或多了括号。

b)双引号和单引号的区别:双引号是字符串型,单引号是字符型。

c) 参数在函数中是否需要定义:

不需要,函数里面只需定义在这个函数里需要用到的一些辅助量,其他引用的量一般在主函数中定义

d)定义一个函数时用void 还是int /char.

如果不需要返回一些值到主函数中,或返回的是数组或指针,就用void

返回的是数值,用int之类

返回的是字符,用char之类

e) 原型声明怎么写

当调用在前,运用在后时,需要原型声明

格式:【数据类型】 <函数名>(形参列表)

从我总结的问题就知道了我上学期真的没学好C++嘤嘤嘤

 

 

本周学习目标:

(1)单日课程单日总结

(2)解决一些还没解决的问题

(3)同时温习一些C++书上的内容,一些基础知识要掌握。

 

posted @ 2019-04-14 20:31  Y000  阅读(386)  评论(1编辑  收藏  举报