【数据结构】第四章学习小结

串、数组

在第四章中,我学到的主要是关于串与数组的内容,至于广义表,既然老师让我们课后有时间去看,那我这里就先不讲广义表了(其实只是粗略的看了一下,还没看懂)

在上学期的c++中我就已经学过有关串的一些知识,对于串还是可以很好的理解的,在数据结构中,串将被看作是一种特殊的线性表,跟线性表一样,串也有两种基本存储结构,个人觉得顺序存储结构对于串的运用比较方便,简单易懂,所以在作业题中会首先考虑使用顺序串。

串有许多很重要的应用,例如搜索引擎,数据压缩等,这些应用都离不开串的模式匹配算法(子串的定位运算)

BF算法:1.利用计数指针i,和j指示主串S和模式串T当天正待比较的字符,将两者皆赋值为1;

        2.将S[i]与T[j]比较,若两者相等,则将i,j分别指向串的下一字符,之后继续比较;

          若不相等,指针就要后退重新匹配,主串回到i=i-j+2的位置上,模式串要回到j=1;(这就是BF算法的时间复杂度远远大于KMP算法的原因)

        3.当j>模式串的长度时,说明匹配成功,此时返回和模式T中第一个字符相等的字符在主串S中的序号,否则返回0,级匹配失败。

优点:匹配过程易于理解,某些场合运行效率高

  缺点:时间复杂度高   

KMP算法:KMP算法看懂了觉得特别简单,思路很简单,看不懂之前,查各种资料,看的稀里糊涂,即使网上最简单的解释,依然看的稀里糊涂。(虽然说 现在还是有点迷糊。)

                  参考了下面的博客:KMP的最浅显理解  https://blog.csdn.net/starstar1992/article/details/54913261/

数组的话,主要研究的是二维数组的运用,在c语言中,二维数组采用的是以行序为主序的存储结构。特殊矩阵的压缩存储是二维数组的一种应用,这里可以使用三元组表和十字链表来解决(十字链表内容在第二章有)

三元组表:

             typedef struct {

               int row; //所在行

                 int column; //所在列

                    int value; //值

                }Node; //定义三元组表

                typedef struct {

                 int rows; //总行

                 int columns; //总列

                       int nums; //非零元素个数

                    Node data[100]; //非零元素 }tupleTable;



接下来就讲讲一些我对实践题第二题:估值上亿的AI这道题的一些理解吧

在听到老师说要教我们在星期四那节课上做出这道题,我是有点怀疑的,毕竟这可是天梯赛的题目,一些大佬都差点被难住了,我表示心里很慌。

当我看到题目的时候,莫名有一种很熟悉的感觉,仔细想想,这不是和上一周程序设计大赛上的一道题目很类似的吗,那时为了做出那道题想了贼久,可惜还是没做出来(哭)

题目
7-2 AI核心代码 (30 分)

本题要求你实现一个简易版的 AI 英文问答程序,规则是:

无论用户说什么,首先把对方说的话在一行中原样打印出来;
消除原文中多余空格:把相邻单词间的多个空格换成 1 个空格,把行首尾的空格全部删掉,把标点符号前面的空格删掉;
把原文中所有大写英文字母变成小写,除了 I;
把原文中所有独立的 I 和 me 换成 you;
把原文中所有的问号 ? 换成惊叹号 !;
把原文中所有独立的 can you 换成 I can —— 这里“独立”是指被空格或标点符号分隔开的单词;
在一行中输出替换后的句子作为 AI 的回答。

输入格式:

输入首先在第一行给出不超过 10 的正整数 N,随后 N 行,每行给出一句不超过 1000 个字符的、以回车结尾的用户的对话,对话为非空字符串,仅包括字母、数字、空格、可见的半角标点符号。

输出格式:

按题面要求输出,每个 AI 的回答前要加上 AI: 和一个空格。

第一步:首先定义数据结构,自然是字符数组/字符串

             最初考虑主函数逻辑,主要是读取输入语句,并调用接口处理输入语句并输出。

           基本流程是,读入一句,对其进行扫描、判断、操作,再存到新的字符串,最后输出新的字符串。

int main()
{
    int n;
    string a;

    cin>>n;
    getchar();/*吸收回车*/
    for(int i=0;i<n;i++)
    {

      getline(cin,a);
    cout<<a<<endl;
    cout<<"AI: ";
         go(a);/*根据a输出AI的回答 */
    }
    return 0;
 } 

第二步:消除多余空格

 for(i=0;a[i]!=‘\0‘&&a[i]==‘ ‘;++i); ;/*最坏情况:全为空格,不会出现越界*/ 

第三步:对输入的语句进行处理:

void go(string a)
{/*根据a输出AI的回答*/
    char t[3002];
    int i,j,k;
    /*i 定位到a的第一个非空*/
     for(i=0;a[i]!=‘\0‘&&a[i]==‘ ‘;++i); ;/*最坏情况:全为空格,不会出现越界*/
     j=0;
      while(a[i]!=‘\0‘)
      {
         if(a[i]==‘ ‘&&a[i-1]==‘ ‘)/*把a串copy到t串,连续空格只copy一次*/
         {
             ++i;
             continue;
         }
         if(a[i]==‘?‘)/*把a串中的“?”换成“!”,写进t串中*/
         {
             t[j]=‘!‘;
             ++i;
             ++j;
             continue;
         }
         if(a[i]!=‘I‘)/*将“I”以外的大写字母统一变成小写字母*/
          {
           t[j]=tolower(a[i]);++i;++j;/*tolower函数:将大写字母转成小写字母*/
           continue;
           }
    t[j++]=a[i++];
     }
    t[j]=‘\0‘;/*在t串后加上一个分隔符*/ 

这里用到了tolower()函数将大写变成小写。将s串的有效都给了t串之后,我们可以遍历t串来进行进一步操作,比如将独立的I和me变成you,有一点要特别注意要在t串之后加一个结尾符,否则会出现一大堆错误,乱码,之类的,很麻烦,当时改了好久,都没发现是这个问题
    k=0;
     while(t[k]!=‘\0‘)
     {

        if(t[k]==‘c‘&&t[k+1]==‘a‘&&t[k+2]==‘n‘&&(k==0||IsIndependent(t[k-1]))&&IsIndependent(t[k+3])&&t[k+4]==‘y‘&&t[k+5]==‘o‘&&t[k+6]==‘u‘&&IsIndependent(t[k+7]))
        {/*把‘can you‘换成’I can‘,同时k要加上‘can you‘的长度*/
            cout<<"I can";
            k=k+7;
            continue;
        }

         if(t[k]==‘I‘&&(k==0||IsIndependent(t[k-1]))&&IsIndependent(t[k+1]))/*将独立的‘I‘转成‘you’*/
         {
            cout<<"you";
            ++k;
            continue;
         }
        if(t[k]==‘m‘&&t[k+1]==‘e‘&&(k==0||IsIndependent(t[k-1]))&&IsIndependent(t[k+2])) /*将独立的‘me‘转成‘you’*/
        {
         cout<<"you";
         k=k+2;
         continue;
        }
        if(t[k]==‘ ‘&&IsIndependent(t[k+1]))
        {
         ++k;
         continue;
        }
      cout<<t[k];
      ++k;
    }
            cout<<endl;
}

以上是第四步,可以将独立的I 换成you独立的you 换成me,按照晓梅老师教给我们的思路,甚至可能是难点将can you 换成 I can 的操作也可以轻松写出来,

判断一个非空格字符是否独立的函数:

bool IsIndependent(char ch)/*判断当前字符是否独立*/
{
    ch=tolower(ch);
    if(ch>=‘0‘&&ch<=‘9‘||ch>=‘a‘&&ch<=‘z‘)
      return false;
    else
     return true;
}

将上述代码整合起来,PTA就基本上没问题了

心得体会:

在解这道题的过程中,我真正体会到了整个解题过程的思路是怎样一步一步出来,必须一个点一个点进行,在以后解题的时候也要学会在过程中对程序进行优化,及时指出错误与不足,学会自己梳理解题思路。

目标的完成情况:

这几周上课都能集中精力,基本没有出现走神的情况,课堂上的学习效果还算达到了预期目标,但是没有及时复习上一章的内容,有点遗憾,平时打的练习题还不够多。

接下来的目标:尽早扫除知识盲区,上次的测验已经给我敲响了警钟,接下来不仅要复习之前学习的内容,更要加把劲,将下一章的预习工作做好,继续去加深对KMP算法的理解。

原文地址:https://www.cnblogs.com/liuzhhhao/p/10707078.html

时间: 2024-10-29 04:32:14

【数据结构】第四章学习小结的相关文章

数据结构第四章学习小结

第四章主要是串和数组的学习,之前对串和数组的应用仅限于对其单独处理,本章学习着重于对具体题目的实际操作,实践了串的模式匹配算法,对其有了更深入的了解,数组的应用拓展到了稀疏矩阵的存储的实现. 一.串 串的模式匹配 BF算法 首先未匹配到串尾时,将两个字符串一一匹配,可用C++自带的length()函数实现 while(i<=S.length()&&j<=T.length()) 接下来就是匹配的过程 if(S[i]==T[j]){ i++;j++; }//若匹配则继续比较下一位

DS第四章学习小结

本章最令人印象深刻的题就是AI核心代码这题了.如下 说实话,刚看到这题真的懵了,虽然只是一道题,但总给人6题的感觉.尽管困难重重,但还是在陈晓梅老师的指导下,大致完成了此题. 逻辑分析 先定义数据结构,自然是字符数组/字符串最初考虑主函数逻辑,主要是读取输入语句,并调用接口处理输入语句并输出.基本流程是,读入一句,对其进行扫描.判断.操作,再存到新的字符串,最后输出新的字符串. 一开始输入部分就卡住了,因为不知道怎么处理回车后还能输入数据,进度就陷入了停滞,不过课上根据老师所说getchar()

第四章学习小结 串的模式匹配 解题心得体会

串的模式匹配 解题心得体会 关于串,模式匹配是其一个很重要的问题.针对这个问题,书上讲了两种模式匹配的算法,即BF算法和KMP算法,下面针对这两种算法的实现谈谈我的心得. 一.BF算法的探索 [错误代码1] #include<iostream> #include<string.h> using namespace std; typedef struct{ char ch[1000002]; int length; }SString; void Index_BF(SString S,

第四章学习小结

这两周上课学的较多且比较有印象的是串的模式匹配算法那道题 同时可以用BF或者KMP算法进行解决. 一开始学BF算法时就在想如何改进可以使匹配更加简便 后来KMP的学习让我对串的学习有了更深入的了解 同时BF和KMP算法之间的联系也是一个算法改进的很好学习范例 7-1 串的模式匹配 给定一个主串S(长度<=10^6)和一个模式T(长度<=10^5),要求在主串S中找出与模式T相匹配的子串,返回相匹配的子串中的第一个字符在主串S中出现的位置. 输入格式: 输入有两行: 第一行是主串S: 第二行是模

数据结构:第二章学习小结

心得体会:经过一周的学习,初步理解顺序表.单链表的概念及初步应用,像顺序表,存储空间一定是连续的,而链表则可以通过指针指向下一个结点的地址,从而使链表的存储空间不连续,真的是很神奇的概念目前存在的困难:不能完全靠自己独立地写出ADT的定义和一些具体的操作,对我现在来说还是有点难度的.不过我相信熟能生巧. 分享的资料:<CLRS 算法导论>——百度直接搜索即可,其他同学有提到过,是一本算法的百科全书.下一阶段的目标:完全理解及独立地完成和完成一些代码的操作,不依靠课本的一些案例,也希望自己能够更

第四章 学习小结

我想谈谈我写模式匹配题时的心得体会: 如果是用BF算法我觉得的这道题真的非常简单,我是用的BF算法, 一开始我把string和书上的sstring搞混淆了 就像下图的代码所示: S.[i]==T.[j] S.length 但是string是头文件<cstring>包含的所以应该打成这样 S[i]==T[j] S.length() 老师上课时讲过这个,但我当时没有认真记下来,课后翻书,就直接按书上的打了,所以就出现错误.后来查阅了相关资料才修改过来了 因为用的是string所以我的BF算法函数如

数据结构第四章总结

数据结构第四章学习的是串,数组和广义表(广义表课程中没讲,问题不大) 串的定义其实在c++学习中就有所接触,所以这里不详说,  重点说的是两个串模式匹配算法 1.BF算法 BF算法的思想就是将目标串S的第一个字符与模式串T的第一个字符进行匹配,若相等,则继续比较S的第二个字符和 T的第二个字符: 若不相等,则比较S的第二个字符和T的第一个字符,依次比较下去,直到得出最后的匹配结果.BF算法是一种蛮力算法. 2.KMP算法 KMP算法的关键是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达

数据结构 第一章学习小结

数据结构   第一章学习小结 1.数据结构第1章的心得体会: 这周学习了数据结构的绪论及第一章.初步了解了数据结构与算法的相关概念,一开始看书看视频时觉得还挺抽象的,不能够完全理解.但是反复多看了几遍之后,结合例题,自己去操作去跑代码,慢慢觉得容易理解接受起来了.由于现在以网课形式进行教学,老师上课的同时基本还是靠自己去理解学习.当然老师也发挥很大的作用,比如让我们更深入的了解递归的空间复杂度为什么与问题规模有关,又怎样去找到该函数的临界值等等.既锻炼了我们深入思考的能力,也让我们更加清楚了解不

第三章学习小结—-转

[学习目标] 01掌握一维数组的声明和使用方法(OK) 02掌握二维数组的声明和使用方法(OK) 03掌握字符串的声明.赋值.比较和连接方法(连接很少用) 04熟悉字符的ASCII码和ctype.h中的字符函数 05正确认识++.+=等能修改变量的运算符(OK) 06学会用编译选项-Wall获得更多的警告信息(OK) 07了解不同操作系统中换行符的表示方法(嗯) 08掌握fgetc和getchar的使用方法(fgetc基本没用过) 09掌握预处理和迭代开发的技巧(嗯) 程序3-1 逆序输出 输入