• 第四章作业题总结


    第四章作业题总结--只谈一些想法

    1、串模式匹配

    7-1 串的模式匹配 (30 分)
     
    给定一个主串S(长度<=10^6)和一个模式T(长度<=10^5),要求在主串S中找出与模式T相匹配的子串,返回相匹配的子串中的第一个字符在主串S中出现的位置。
    
    输入格式:
    输入有两行: 第一行是主串S; 第二行是模式T.
    
    输出格式:
    输出相匹配的子串中的第一个字符在主串S中出现的位置。若匹配失败,输出0.
    
    输入样例:
    
    在这里给出一组输入。例如:
    aaaaaba
    ba
    
    输出样例:
    在这里给出相应的输出。例如:
    6
    View Code
    作者: 陈晓梅
    单位: 广东外语外贸大学
    时间限制: 400 ms
    内存限制: 64 MB
    代码长度限制: 16 KB
     
    这道题主要是考我们对KMP算法的一个应用,虽然BF算法也可以,但是再某些数据量特别大的时候,就有点不太适合了,我已经在第四章总结里面写了关于这个算法的一些内容,这个就直接放代码吧。
     
    代码如下:
     
    #include<iostream>
    #include<string.h>
    using namespace std;
    
    /*这次题目中,既有如题所示的几个小小的字符串
    也有测试数据中的 10^5、10^6的大数据,因此需要kmp算法
    不过后续会尝试一下BF算法 
    */ 
    
    char *jg (string str)//返回一整个函数 
    {
        int size = str.length();
        char *s;
        s = new char[size];
        strcpy(s,str.c_str());//strcpy是一种C语言的标准库函数,strcpy把含有''结束符的字符串复制到另一个地址空间,返回值的类型为char* 
        return s;
     } 
    
    void calc_next(string pstring, int *next)
    {//设计一个函数next,来修正next的数值
        next[0] = -1;//表示模式串的开头,为-1,否则会错位
        int j = 0, k = -1; 
        int plen = pstring.length();//模式串的长度     
        char *p = jg(pstring);//模式串的字符数组
        while (j < plen)
        {
            if(k == -1 || p[j] == p[k])
            {
                k++;
                j++;
                next[j] = k;/*next数组存放着已匹配的子串中最长的前后缀,
                next[j]  表示p[0]-p[j] 子串中最长的前后缀长度*/ 
            }
            else{
                k = next[k]; //k回溯到模式串的开头 
            }
         } 
        
    }
    
    int kmp( string s, string pstring)
    {
        int *next = new int [pstring.length()];
        calc_next(pstring,next);//得到 next[]数组
        char *c = jg(s);
        char *p = jg(pstring);
        //转换字符串为字符数组 
        int i=0,j=0;
        int pos = 0;
        while( i<=s.length()|| j<=pstring.length() )
        {
            if(j ==-1 || c[i] == p[j]){
                i++;
                j++;
                
            }
            else{
                j = next[j];//
            }
                        /* 
                        (1)有着最长前后缀的时候,主串与模式串在主串s[j]的位置(模式串最长后缀后一位)
                        不匹配的时候の 时候,s[j]将会与模式串的最长前后缀的后一位进行比较
                        (2)没有最长前后缀的时候,整个模式串后移一位   */
    
              
            if(j == pstring.length()){//匹配成功 
                pos = i-j+1;
                break;
            } 
            
        }
            return pos;
     } 
    
    
    
    int main()
    {
        string s, pstring;//定义字符串 ,模式串  
        getline(cin, s);//输入字符串 
        getline(cin, pstring);//输入模式串 
        
        cout<<kmp(s, pstring);
        return 0;
    }
    View Code
    关于string函数的一些内容:
     String 对象是 System Char 对象的有序集合,用于表示字符串。String 对象的值是该有序集合的内容,并且该值是不可变的
    String就是C++、JAVA、VB等编程语言中的字符串,用双引号引起来的几个字符.如"Abc","一天".
      string的子串:
    1
    string substr(int pos = 0,int n = npos) const;//返回pos开始的n个字符组成的字符串
      string的比较:
      bool operator==(const string &s1,const string &s2)const;//比较两个字符串是否相等 运算符">","<",">=","<=","!="均被重载用于字符串的比较;
      int compare(const string &s) const;//比较当前字符串和s的大小
      int compare(int pos, int n,const string &s)const;//比较当前字符串从pos开始的n个字符组成的字符串与s的大小
      int compare(int pos, int n,const string &s,int pos2,int n2)const;//比较当前字符串从pos开始的n个字符组成的字符串与s中//pos2开始的n2个字符组成的字符串的大小
      int compare(const char *s) const;
      int compare(int pos, int n,const char *s) const;
      int compare(int pos, int n,const char *s, int pos2) const;//compare函数在大于(>)时返回1,小于(<)时返回-1,等于(==)时返回0
      string的一些函数构造:
      string();
      string( size_type length, char ch );
      string( const char *str );
      string( const char *str, size_type length );
      string( string &str, size_type index, size_type length );
      string( input_iterator start, input_iterator end );
     
     
    资料来源:
    https://baike.baidu.com/item/string/5137266?fr=aladdin
    https://www.cnblogs.com/aminxu/p/4686320.html
     

    2、稀疏矩阵

    7-1 稀疏矩阵 (30 分)
    如果一个矩阵中,0元素占据了矩阵的大部分,那么这个矩阵称为“稀疏矩阵”。对于稀疏矩阵,传统的二维数组存储方式,会使用大量的内存来存储0,从而浪费大量内存。为此,可以用三元组的方式来存放一个稀疏矩阵。
    
    对于一个给定的稀疏矩阵,设第r行、第c列值为v,且v不等于0,则这个值可以表示为。这个表示方法就称为三元组。那么,对于一个包含N个非零元素的稀疏矩阵,就可以用一个由N个三元组组成的表来存储了。
    
    如:{<1, 1, 9>, <2, 3, 5>, <10, 20, 3>}就表示这样一个矩阵A:A[1,1]=9,A[2,3]=5,A[10,20]=3。其余元素为0。
    
    要求查找某个非零数据是否在稀疏矩阵中,如果存在则输出其行列下标,不存在则输出ERROR。
    
    输入格式:
    共有N+2行输入: 第一行是三个整数m, n, N(N<=500),分别表示稀疏矩阵的行数、列数和矩阵中非零元素的个数,数据之间用空格间隔; 随后N行,输入稀疏矩阵的非零元素所在的行、列值和非零元素的值; 最后一行输入要查询的非0数据k。
    
    输出格式:
    如果存在则输出其行列下标,不存在则输出ERROR。
    
    输入样例:
    在这里给出一组输入。例如:
    
    10 29 3
    2 18 -10
    7 1 98
    8 10 2
    2
    输出样例:
    在这里给出相应的输出。例如:
    
    8 10
    View Code
    作者: 陈晓梅
    单位: 广东外语外贸大学
    时间限制: 400 ms
    内存限制: 64 MB
    代码长度限制: 16 KB
     
    关于本题的话,我感觉就是在为数学做一个exe
    (1)三个整数,m(行)、n(列)、N(个非零元素)

    (2)输入:1)m、n、N的值

         2)非零元所在的行、列、值

          3)最后一行输入的一个数字是需要查找的值
    (3)输出:1)输入的数字在改矩阵中则输出行与列
          2)不在则输出ERROR
     
    那么首先是输入这三个数,然后扩充数组,然后输入需要查询的数值,最后引入一个flag--最喜欢flag了,用flag的值来判断来输出即可
     
    代码(完全自己写的哼唧唧,我好棒)
     (怕被老师“打”还是折叠吧)
    #include<iostream>
    using namespace std;
    
    int main()
    {
    int m,n,N;
    cin>>m>>n>>N;//行列和个数 
    N=3*N;
        
    int a[N];
    
    for(int i=0;i<N;i++)
    {
        cin >> a[i];
     }//输入三个元素 
     
     int c,flag=0;
     
    cin >> c;//输入需要查询的数 
    
    int j=2;
    
    for(j=2;j<N;j=j+3)
    {
        if (c==a[j]) 
        {flag=0;
        break;
        }
        
        else {
            flag=1;
            continue;
        } 
    }//只与输入的非零元素进行比较 
    
    if(flag == 0) 
    cout<<a[j-2]<<" "<<a[j-1]<<endl;
    
    else 
    cout<<"ERROR"<<endl;//对,就输出,不对就是ERROR 
    
    return 0;
    }
    View Code
    3、AI之题
    7-2 AI核心代码 (30 分)
    本题要求你实现一个简易版的 AI 英文问答程序,规则是:
    
    无论用户说什么,首先把对方说的话在一行中原样打印出来;
    消除原文中多余空格:把相邻单词间的多个空格换成 1 个空格,把行首尾的空格全部删掉,把标点符号前面的空格删掉;
    把原文中所有大写英文字母变成小写,除了 I;
    把原文中所有独立的 I 和 me 换成 you;
    把原文中所有的问号 ? 换成惊叹号 !;
    把原文中所有独立的 can you 换成 I can —— 这里“独立”是指被空格或标点符号分隔开的单词;
    在一行中输出替换后的句子作为 AI 的回答。
    输入格式:
    输入首先在第一行给出不超过 10 的正整数 N,随后 N 行,每行给出一句不超过 1000 个字符的、以回车结尾的用户的对话,对话为非空字符串,仅包括字母、数字、空格、可见的半角标点符号。
    
    输出格式:
    按题面要求输出,每个 AI 的回答前要加上 AI: 和一个空格。
    
    输入样例:
    在这里给出一组输入。例如:
    
    6
    Hello ?
     Good to chat   with you
    can   you speak Chinese?
    Really?
    Could you show me 5
    What Is this prime? I,don 't know
    输出样例:
    在这里给出相应的输出。例如:
    
    Hello ?
    AI: hello!
     Good to chat   with you
    AI: good to chat with you
    can   you speak Chinese?
    AI: I can speak chinese!
    Really?
    AI: really!
    Could you show me 5
    AI: could you show you 5
    What Is this prime? I,don 't know
    AI: what Is this prime! you,don't know
    View Code

      

    作者: 未知
    单位: 未知
    时间限制: 400 ms
    内存限制: 64 MB
    代码长度限制: 16 KB
     
    貌似是某个天梯赛的一道题??我也不懂,反正老师拉过来给我们当作业了
     
    但是在老师的引导下,我觉得本题的思考就是:
    先把主函数写出来,同时开始弄几个结构,再根据题目给的信息一步一步将接口完善
    (PS:一定要注意那个 == 和 = 的区别,改了一下午,就是有个地方不能通过,最后一个个看,发现多了一个 = 最后输出结果总是错的)
     
    #include<iostream>
    #include<cstring> 
    #include<cstdio>
    using namespace std;
    
    //string s;
    //char s[1001]; 
    
    bool isDependent(char ch)
    {//判断ch是否为分隔字符
        ch = tolower(ch);
        if(ch>='0'&&ch<='9'|| ch>='a'&& ch<='z')
             return false;
        else 
            return true;
        
    }
    
    bool isCanyou(char t[],int j)            //判断一个独立的can you 
    {
        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'){
            if((j==0 || isDependent(t[j-1]) ) && isDependent(t[j+7]))
                return true; 
        }
        else
            return false;
    }
    
    void go(string s)
    {//根据s输出 
    char t[3003];//1000个大I 
    //    string t =="";//无初始化,无法保存 
        //尝试开头的空格删去
        int i,j;//i:定位s的第一个非空 
        
        for(i=0;s[i] !='' && s[i] ==' ';++i);//全部是空格,无边界,因为输入最后的空格改成; 
        
            j = 0;
            
            while(s[i]!=''){//把s串copy到t,连续的字符“ ”只复制一个 
            if(s[i]==' ' && s[i-1]==' ')
            {
            ++i;
            continue ;
            }    
                                        
            if(s[i]=='?')
            { 
            t[j]='!';//改问号为感叹号
            i++;
            j++;
            continue; 
            }
                
            if(s[i]!='I')
            {t[j] = tolower(s[i]);
            j++;
            i++;
            }//利用tolower 
                else{t[j++] = s[i++]; }
                 
            }
            t[j] = ''; 
            
        //把原文中所有独立的 I 和 me 换成 you,所有独立的 can you 换成 I can        
            j=0;    
            while(t[j]!=''){
                if(t[j]=='I' && (j==0 || isDependent(t[j-1])) && isDependent(t[j+1])){ //I换成you 
                    cout<<"you";
                    ++j;
                    continue;
                }
                
                if(t[j]=='m' && t[j+1]=='e' && (j==0|| isDependent(t[j-1])) && isDependent(t[j+2]))    //me换成you
                {
                    cout << "you";
                    j=j+2;
                    continue;
                }
                
            if(isCanyou(t,j) && isDependent(t[j-1]) && isDependent(t[j+7])){            //can you换成I can 
            
                cout << "I can";
                j+=7;
                continue;
            }        
                
                if(t[j]==' '&& isDependent(t[j+1])){
                    ++j;
                    continue;
                }
            
            cout << t[j];
            ++j;
        }    
         cout<<endl;
     }
    
    int main()
    {
        int n;
        string s;
        cin >> n;
        getchar();//吸收回车 
        for(int i=0; i<n; i++)
        {
            getline(cin,s);
            
            cout << s << endl;
            cout << "AI: " ;
            go(s);//根据s(作为参数要传给go函数) 输出AI回答
         } 
         
    return 0;
    }
    
     
    View Code
     
    我觉得老师写的博客其实就很好了,强推:
    https://www.cnblogs.com/cxmCnBlogs/p/10691278.html
     
  • 相关阅读:
    AngularJS实现跨域请求
    从古代名著看领导与被领导的艺术
    关于学习视频教程的反思之中的一个
    关于tcp中time_wait状态的4个问题
    AjaxPro因为汉字文件夹引发的IE兼容性问题
    MySQL无法重启问题解决Warning: World-writable config file ‘/etc/my.cnf’ is ignored
    安全运维之:Linux系统账户和登录安全
    mongodb导入导出备份恢复
    mongodb数据库备份恢复
    mongodb
  • 原文地址:https://www.cnblogs.com/JeffKing11/p/10666505.html
Copyright © 2020-2023  润新知