zoukankan      html  css  js  c++  java
  • 『嗨威说』数据结构

      一道天梯赛搞得全场人崩溃的题,几乎现场就没几个人AC,现在回头看看,真的很考细节耐心地题目。

    -----------------------------题目-----------------------------

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

    -----------------------------题目-----------------------------

    一、正式题解:

        1* 函数原型声明:

    void deleteSymbolSpace();
    void deleteSpace();
    void bigToSmall();
    void changePersonY();
    void changePersonI();
    void changeQ();
    bool isIndenpend(char temp);

          deleteSymbolSpace —— 删除符号前的空格

          deleteSpace —— 删除多余空格

          bigToSmall —— 将大写转小写

          changePersonY —— 改变人称You

          changePersonI —— 改变人称I me

          changeQ —— 问号改为感叹号

          isIndenpend —— 判断是否独立函数

        2* 主函数框架构建:

    int main()
    {
        scanf("%d",&times);
        getchar();
        while(times--)
        {
            memset(temp,0,sizeof(temp));
            memset(tMark,0,sizeof(tMark));
            cin.getline(temp,2000);
            puts(temp);
            changeQ();
            bigToSmall();
            deleteSpace();
            changePersonY();
            changePersonI();
            deleteSpace();
            deleteSymbolSpace();
            printf("AI: ");
            puts(temp);
        }
        return 0;
    }

          抛开细节的实现方式,从大局角度思考程序的运行方式。

        3*deleteSymbolSpace的实现:

    void deleteSymbolSpace()
    {
        memset(dealing,0,sizeof(dealing));
        count = 0;
        for(int i = 0;i<strlen(temp);i++)
        {
            if(temp[i] == 32)
            {
                int flag = 0;
                if(temp[i+1]>=33 && temp[i+1]<=47) flag = 1;
                else if(temp[i+1]>=58 && temp[i+1]<=64) flag = 1;
                else if(temp[i+1]>=91 && temp[i+1]<=96) flag = 1;
                else if(temp[i+1]>=123 && temp[i+1]<=126) flag = 1;
                
                if(flag == 1)
                {
                    dealing[count] = temp[i+1];
                    count++;
                    i=i+1;
                }
                else
                {
                    dealing[count] = temp[i];
                    count++;
                }
            }
            else
            {
                dealing[count] = temp[i];
                count++;
            }
        }
        dealing[count] = '';
        memset(temp,0,sizeof(temp));
        strcpy(temp,dealing);
    }

        因为刚开始不知道判断字母和数字的函数,所以干脆直接简单粗暴,ASCII扫独立。

        4* deleteSpace函数的实现:

    void deleteSpace()
    {
        int start = 0;
        int space = 0;
        memset(dealing,0,sizeof(dealing));
        count = 0;
        for(int i = 0;i<strlen(temp);i++)
        {
            if(start == 0 && temp[i] == 32) continue;
            else if(start == 0 && temp[i] != 32)
            {
                start = 1;
                dealing[count] = temp[i];
                count++;
                continue;
            }
            
            if(temp[i] == 32)
            {
                if(space == 1) continue;
                if(tMark[i] == 1) continue;
                space = 1;
                dealing[count] = 32;
                count++;
            }
            else
            {
                space = 0;
                dealing[count] = temp[i];
                count++;
            }
        }
        if(dealing[count-1] == 32) dealing[count-1] = '';
        else dealing[count] = '';
        memset(temp,0,sizeof(temp));
        strcpy(temp,dealing);
    }

        核心思路很简单,就是拿一个新数组去存新的结果,通过打标记判断是否是句头空行。

        5* bigToSmall函数的实现:

    void bigToSmall()//实际上可以用tolower代替 
    {
        for(int i = 0;i<strlen(temp);i++)
        {
            if( temp[i] >= 65 && temp[i] <= 90)
            {
                if(temp[i] == 'I') continue;
                temp[i] = temp[i] + 32;
            }
        }
    }

          这里也是因为不知道有tolower这个魔鬼函数,所以依旧简单粗暴,暴力用ASCII解决问题。

        6* changePersonY函数的实现:

    void changePersonY()
    {
        for(int i = 0;i<strlen(temp);i++)
        {
            int flag = -1;
            if(i != 0 && !isIndenpend(temp[i-1])) continue;
            if(temp[i] == 'c' && temp[i+1] == 'a' && temp[i+2] == 'n') flag = 3;
            else if(temp[i] == 'c' && temp[i+1] == 'o' && temp[i+2] == 'u' && temp[i+3] == 'l' && temp[i+4] == 'd') flag = 5;
            
            if(flag != -1)
            {
                int mark = 0;
                if(temp[i+flag]>=32 && temp[i+flag]<=47) mark = 1;
                else if(temp[i+flag]>=58 && temp[i+flag]<=64) mark = 1;
                else if(temp[i+flag]>=91 && temp[i+flag]<=96) mark = 1;
                else if(temp[i+flag]>=123 && temp[i+flag]<=126) mark = 1;
                if(mark == 1)
                {
                    if(temp[i+flag+mark] == 'y' && temp[i+flag+mark+1] == 'o' && temp[i+flag+mark+2] == 'u')
                    {
                        if(temp[i+flag+mark+3] != '' && !isIndenpend(temp[i+flag+mark+3])) continue;
                        temp[i] = 'I';
                        tMark[i] = 1;
                        temp[i+1] = temp[i+flag];
                        if(flag == 3)
                        {
                            temp[i+2] = 'c';
                            temp[i+3] = 'a';
                            temp[i+4] = 'n';
                        }
                        else if(flag == 5)
                        {
                            temp[i+2] = 'c';
                            temp[i+3] = 'o';
                            temp[i+4] = 'u';
                            temp[i+5] = 'l';
                            temp[i+6] = 'd';
                        }
                        
                        temp[i +flag+2] = ' ';
                        temp[i +flag+3] = ' ';
                        tMark[i +flag+2] = tMark[i +flag+3] = 1;
                        i = i +flag+3;
                    }
                }
            }
        }
    }

         转换人称是所有限制条件最麻烦最难的地方,需要注意打上标记,因为对string还是有点小反感,虽然挺好用,但是习惯用char进行单个强行处理,所以这里一直是用char来处理的~ 

        7* changePersonI函数的实现:

    void changePersonI()
    {
        memset(dealing,0,sizeof(dealing));
        count = 0;
        for(int i = 0;i<strlen(temp);i++)
        {
            if(temp[i] == 'I' && isIndenpend(temp[i+1]) && tMark[i] == 0)
            {
                if(i != 0 && !isIndenpend(temp[i-1])) 
                {
                    dealing[count] = temp[i];
                    count++;
                    continue;
                }
                dealing[count] = 'y';
                dealing[count+1] = 'o';
                dealing[count+2] = 'u';
                count += 3;
            }
            else if(temp[i] == 'm' && temp[i+1] == 'e' && isIndenpend(temp[i+2]))
            {
                if(i != 0 && !isIndenpend(temp[i-1]))
                {
                    dealing[count] = temp[i];
                    count++;
                    continue;
                }
                dealing[count] = 'y';
                dealing[count+1] = 'o';
                dealing[count+2] = 'u';
                count += 3;
                i = i + 1;
            }
            else
            {
                dealing[count] = temp[i];
                count++;
            }
        }
        dealing[count] = '';
        memset(temp,0,sizeof(temp));
        strcpy(temp,dealing);
    }

          这里尤其需要注意,不能把已经换过的人称再换一次,所以需要对标记进行判断。

        8* changeQ的函数实现:

    void changeQ()
    {
        for(int i = 0;i<strlen(temp);i++)
            if(temp[i] == '?')
                temp[i] = '!';
    }

          尽管函数简单,但尽量单独列出,使程序更加结构化。

        9* isIndenpend函数的实现:

    bool isIndenpend(char temp)
    {
        int mark = 0;
        if(temp>=32 && temp<=64) mark = 1;
        else if(temp>=91 && temp<=96) mark = 1;
        else if(temp>=123 && temp<=126) mark = 1;
        else if(temp == '') mark = 1;
        return mark;
    }

          暴力ASCII码解决,虽然不是最佳的处理方式。

    二、完整代码展示:

    #include<stdio.h>
    #include<string.h>
    #include<iostream>
    using namespace std;
    
    //------------------------
    void deleteSymbolSpace();
    void deleteSpace();
    void bigToSmall();
    void changePersonY();
    void changePersonI();
    void changeQ();
    bool isIndenpend(char temp);
    //------------------------
    
    int times;
    char dealing[2001];
    int count;
    char temp[2001];
    int tMark[2001];
    int main()
    {
        scanf("%d",&times);
        getchar();
        while(times--)
        {
            memset(temp,0,sizeof(temp));
            memset(tMark,0,sizeof(tMark));
            cin.getline(temp,2000);
            puts(temp);
            changeQ();
            bigToSmall();
            deleteSpace();
            changePersonY();
            changePersonI();
            deleteSpace();
            deleteSymbolSpace();
            printf("AI: ");
            puts(temp);
        }
        return 0;
    }
    
    void deleteSymbolSpace()
    {
        memset(dealing,0,sizeof(dealing));
        count = 0;
        for(int i = 0;i<strlen(temp);i++)
        {
            if(temp[i] == 32)
            {
                int flag = 0;
                if(temp[i+1]>=33 && temp[i+1]<=47) flag = 1;
                else if(temp[i+1]>=58 && temp[i+1]<=64) flag = 1;
                else if(temp[i+1]>=91 && temp[i+1]<=96) flag = 1;
                else if(temp[i+1]>=123 && temp[i+1]<=126) flag = 1;
                
                if(flag == 1)
                {
                    dealing[count] = temp[i+1];
                    count++;
                    i=i+1;
                }
                else
                {
                    dealing[count] = temp[i];
                    count++;
                }
            }
            else
            {
                dealing[count] = temp[i];
                count++;
            }
        }
        dealing[count] = '';
        memset(temp,0,sizeof(temp));
        strcpy(temp,dealing);
    }
    
    
    void deleteSpace()
    {
        int start = 0;
        int space = 0;
        memset(dealing,0,sizeof(dealing));
        count = 0;
        for(int i = 0;i<strlen(temp);i++)
        {
            if(start == 0 && temp[i] == 32) continue;
            else if(start == 0 && temp[i] != 32)
            {
                start = 1;
                dealing[count] = temp[i];
                count++;
                continue;
            }
            
            if(temp[i] == 32)
            {
                if(space == 1) continue;
                if(tMark[i] == 1) continue;
                space = 1;
                dealing[count] = 32;
                count++;
            }
            else
            {
                space = 0;
                dealing[count] = temp[i];
                count++;
            }
        }
        if(dealing[count-1] == 32) dealing[count-1] = '';
        else dealing[count] = '';
        memset(temp,0,sizeof(temp));
        strcpy(temp,dealing);
    }
    
    void bigToSmall()//实际上可以用tolower代替 
    {
        for(int i = 0;i<strlen(temp);i++)
        {
            if( temp[i] >= 65 && temp[i] <= 90)
            {
                if(temp[i] == 'I') continue;
                temp[i] = temp[i] + 32;
            }
        }
    }
    
    void changePersonY()
    {
        for(int i = 0;i<strlen(temp);i++)
        {
            int flag = -1;
            if(i != 0 && !isIndenpend(temp[i-1])) continue;
            if(temp[i] == 'c' && temp[i+1] == 'a' && temp[i+2] == 'n') flag = 3;
            else if(temp[i] == 'c' && temp[i+1] == 'o' && temp[i+2] == 'u' && temp[i+3] == 'l' && temp[i+4] == 'd') flag = 5;
            
            if(flag != -1)
            {
                int mark = 0;
                if(temp[i+flag]>=32 && temp[i+flag]<=47) mark = 1;
                else if(temp[i+flag]>=58 && temp[i+flag]<=64) mark = 1;
                else if(temp[i+flag]>=91 && temp[i+flag]<=96) mark = 1;
                else if(temp[i+flag]>=123 && temp[i+flag]<=126) mark = 1;
                if(mark == 1)
                {
                    if(temp[i+flag+mark] == 'y' && temp[i+flag+mark+1] == 'o' && temp[i+flag+mark+2] == 'u')
                    {
                        if(temp[i+flag+mark+3] != '' && !isIndenpend(temp[i+flag+mark+3])) continue;
                        temp[i] = 'I';
                        tMark[i] = 1;
                        temp[i+1] = temp[i+flag];
                        if(flag == 3)
                        {
                            temp[i+2] = 'c';
                            temp[i+3] = 'a';
                            temp[i+4] = 'n';
                        }
                        else if(flag == 5)
                        {
                            temp[i+2] = 'c';
                            temp[i+3] = 'o';
                            temp[i+4] = 'u';
                            temp[i+5] = 'l';
                            temp[i+6] = 'd';
                        }
                        
                        temp[i +flag+2] = ' ';
                        temp[i +flag+3] = ' ';
                        tMark[i +flag+2] = tMark[i +flag+3] = 1;
                        i = i +flag+3;
                    }
                }
            }
        }
    }
    
    void changePersonI()
    {
        memset(dealing,0,sizeof(dealing));
        count = 0;
        for(int i = 0;i<strlen(temp);i++)
        {
            if(temp[i] == 'I' && isIndenpend(temp[i+1]) && tMark[i] == 0)
            {
                if(i != 0 && !isIndenpend(temp[i-1])) 
                {
                    dealing[count] = temp[i];
                    count++;
                    continue;
                }
                dealing[count] = 'y';
                dealing[count+1] = 'o';
                dealing[count+2] = 'u';
                count += 3;
            }
            else if(temp[i] == 'm' && temp[i+1] == 'e' && isIndenpend(temp[i+2]))
            {
                if(i != 0 && !isIndenpend(temp[i-1]))
                {
                    dealing[count] = temp[i];
                    count++;
                    continue;
                }
                dealing[count] = 'y';
                dealing[count+1] = 'o';
                dealing[count+2] = 'u';
                count += 3;
                i = i + 1;
            }
            else
            {
                dealing[count] = temp[i];
                count++;
            }
        }
        dealing[count] = '';
        memset(temp,0,sizeof(temp));
        strcpy(temp,dealing);
    }
    
    void changeQ()
    {
        for(int i = 0;i<strlen(temp);i++)
            if(temp[i] == '?')
                temp[i] = '!';
    }
    
    bool isIndenpend(char temp)
    {
        int mark = 0;
        if(temp>=32 && temp<=64) mark = 1;
        else if(temp>=91 && temp<=96) mark = 1;
        else if(temp>=123 && temp<=126) mark = 1;
        else if(temp == '') mark = 1;
        return mark;
    }

    三、个人反思:

        AI这道题还有待进一步优化和升级,还有一个bug没有发现,还会继续解决,重点想讲的是程序设计的架构:

        框架化的程序设计方法,是很早在Quanta冬令营中安卓JAVA的设计学习而得,由此类比过来的。我觉得,倘若要成为合格的程序设计师,出外工作的话,对框架的把握是非常重要的一个关卡,代码是否结构化明显,是否符合公司开发要求,是否易读都是程序设计过程中非常关键的地方。在安卓中,有分层WEB层、底层、数据层、素材动画层等等,选用合理的框架,能对团队的程序设计带来极大的效益,因此这个思想需要坚持并保留下来。

        接下来的学习历程吧:

        =》学习十字链表以及线性树、主席树、区间更新等ACM问题,为5月12日的广东省ACM省赛做准备

        =》学习统计学习方法,掌握模型评估、决策树、向量机等知识,为数据挖掘实验室——多模态情感分析项目组努力。

        =》前阵子七周都在英剧上花了不少时间,学习有些耽误,后续时间将慢慢追回学业,保证学业状态。

        哦对了,顺便附加ACM中的KMP模板吧,挺好用的,直接背下来用就好了~

    int KMP(char* str,char* pat)
    {
        int i,j,k;
        memset(fail,-1,sizeof(fail));
        for(i = 1;pat[i];++i)
        {
            for(k = fail[i-1];k>=0 && pat[i] != pat[k+1];k = fail[k]);
            if(pat[k+1] == pat[i]) fail[i] = k + 1;
        }
        i = j = 0;
        while(str[i] && pat[j])
        {
            if(pat[j] == str[i]) ++i,++j;
            else if(j == 0) ++i;
            else j = fail[j-1] + 1;
        }
        if(pat[j]) return 0;
        else return i-j+1;
     }
    View Code
  • 相关阅读:
    mojo 接口示例
    MojoliciousLite: 实时的web框架 概述
    接口返回json
    centos 6.7 perl 版本 This is perl 5, version 22 安装DBI DBD
    centos 6.7 perl 5.22 安装DBD 需要使用老的perl版本
    商业智能改变汽车行业
    商业智能改变汽车行业
    读MBA经历回顾(上)目的决定手段——北漂18年(48)
    perl 升级到5.20版本
    Group Commit of Binary Log
  • 原文地址:https://www.cnblogs.com/WinniyGD/p/10708279.html
Copyright © 2011-2022 走看看