• 《数据结构》第4章小结


    这次的小结主要是讲自己做题的感受。那就开门见山吧。

    我想说的题是↓↓↓

     

    没错,就是AI核心算法。这个题目是老师上机课讲的一个题目,由于我上课有点跟不上节奏,所以导致了一下结果↓↓↓

     

    每次看到这些都很绝望啊,大家有没有这样感觉。。之后自己回去琢磨了一下子并且借鉴网上的大神的代码,自己也把这个程序跑了一遍,长时间自闭之后终于迎来了甘露。现在我就来说一下自己的思路吧。

    首先是根据老师讲过的思路把main函数本层次写好。

    int main() {
        int n;     
        string s;
        cin >> n; 
       getchar(); //吸收回车符 
    for (int i = 1; i <= n; i++) { getline(cin, s); cout << s << endl; //先输出原话,再输出处理后的AI回答 cout << "AI: "; answer(); //处理并输出回答 } return 0; }

    接下来,就是要具体实现answer函数了。

    void answer(string s) {        //根据s处理并输出回答
        string t;    //t为处理后的字符
        int i, j = 0;        //i定位到s的第一个非空,j表示t串的字符
        for (i = 0; s[i] == ' '; i++) {    
            //仅仅用于定位.因为字符串有个结尾符‘\0’,所以及时字符串全空,到最后的结尾符也会停止循环
        }
        while (s[i] != '\0') {    //进行输入
            if (s[i] == ' '&&s[i - 1] == ' ') {        //跳过多余的空格
                i++;
                continue;
            }
            t[j] = s[i];    //将s串的非空或者单个空格给到t串,之后分别+1进行下一轮输入
            j++;
            i++;
        }
     }
    View Code

    以上就是先弄好处理空格的问题。

    接下来就把符号改变。
    将s串的有效字符都给了t串之后,我们可以遍历t串来进行操作。

     answer(string s) {
        string t;    //t为处理后的字符串
        int i, j = 0;        //i定位到s的第一个非空,j表示t串的字符
        for (i = 0; s[i] == ' '; i++) {
    
        }
        while (s[i] != '\0') {    //进行输入
            if (s[i] == ' '&&s[i - 1] == ' ') {        //跳过多余的空格
                i++;
                continue;
            }
            if (s[i] == '?') {        //将输入的问号变为感叹号
                t[j] = '!';
                i++;
                j++;
                continue;
            }
    
            if (s[i] != 'I') {        //将除了I的大写变小写
                t[j] = tolower(s[i]);
                i++;
                j++;
            }
            else {
                t[j] = s[i];    //将s串的非空或者单个空格给到t串,之后分别+1进行下一轮输入
                j++;
                i++;
            }
        }
        t[j] = '\0';    //为t串末尾增加结尾符
    View Code

    下面将me 改为 you

    j = 0;
        while (t[j] != '\0') {
            //独立的I,意味着左右均是分隔符
            if (t[j] == 'I'&&(j==0||isIndependent(t[j - 1])) && isIndependent(t[j + 1])) {            
                cout << "you";
                j++;
                continue;
            }
            //独立的me
            if (t[j] == 'm'&&t[j + 1] == 'e'&& (j == 0 || isIndependent(t[j - 1])) && isIndependent(t[j + 2])) {    
                cout << "you";
                j += 2;
                continue;
            }
    View Code
    bool isIndependent(char ch) {
        bool result = true;
        ch = tolower(ch);
        if ((ch >= '0' && ch <= '9') || (ch >= 'a'&&ch <= 'z')) {
            result = false;
        }
        return result;
    }
    View Code

    标点前的空格

    //如果是标点前的空格就不输出
            if (t[j] == ' '&&isIndependent(t[j+1])) {
                j++;
                continue;
            }
            cout << t[j];
            j++;
        }
    View Code

    can you 变 I can

    最后就是一块硬骨头头了,用一些巧妙的方法嘻嘻

    //判断是否为独立的can you
    bool isCanyou(char ch[],int n) {
        bool result = false;
        if (ch[n] == 'c'&&ch[n + 1] == 'a'&&ch[n + 2] == 'n'&&ch[n + 3]==' ' && ch[n + 4] == 'y'&&ch[n + 5] == 'o'&&ch[n + 6] == 'u') {
            if ((n == 0 || isIndependent(ch[n - 1])) && isIndependent(ch[n + 7])) {
                result = true;
            }
        }
        return result;
    }
    View Code
    //独立的can you
            if (isCanyou(t, j)) {
                cout << "I can";
                j += 7; //can you 是7个字符长度,所以我们跳过它,直接输出I can
                continue;
            }
    View Code

    最后就是ac代码

    #include <iostream>
    #include <string>
    #include <cstring>
    #include <cstdio>
    
    using namespace std;
    
    void answer(string s);
    bool isIndependent(char ch);
    bool isCanyou(char ch[], int n);
    void putIn(string s, char t[], int &i, int &j);
    void print(char t[], int &j);
    
    int main() {
        int n;    
        string s;
        cin >> n;
        getchar();
        for (int i = 1; i <= n; i++) {
            getline(cin, s);
            cout << s << endl;        //先输出原话,再输出处理后的AI回答
            cout << "AI: ";
            answer(s);    //处理并输出回答
        }
        return 0;
    }
    
    //根据s处理并输出回答
    void answer(string s) {
        char t[3002];    //t为处理后的字符串
        int i, j = 0;        //i定位到s的第一个非空,j表示t串的字符
        for (i = 0; s[i] == ' '; i++) {
        
        }
        putIn(s, t, i, j);    //把s输入给t
        t[j] = '\0';    //为t串末尾增加结尾符
        j = 0;        //为方便遍历将j置零
        print(t,j);        //遍历t并一顿操作后输出,主要把I,me变成you; can you 换成 I can
        cout << endl;
    }
    
    //判断字符是否为分隔符
    bool isIndependent(char ch) {
        bool result = true;
        ch = tolower(ch);
        if ((ch >= '0' && ch <= '9') || (ch >= 'a'&&ch <= 'z')) {
            result = false;
        }
        return result;
    }
    
    //判断是否为独立的can you
    bool isCanyou(char ch[],int n) {
        bool result = false;
        if (ch[n] == 'c'&&ch[n + 1] == 'a'&&ch[n + 2] == 'n'&&ch[n + 3]==' ' && ch[n + 4] == 'y'&&ch[n + 5] == 'o'&&ch[n + 6] == 'u') {
            if ((n == 0 || isIndependent(ch[n - 1])) && isIndependent(ch[n + 7])) {
                result = true;
            }
        }
        return result;
    }
    
    //把s输入给t
    void putIn(string s, char t[],int &i, int &j) {
        while (s[i] != '\0') {    
            if (s[i] == ' '&&s[i - 1] == ' ') {        //跳过多余的空格
                i++;
                continue;
            }
            if (s[i] == '?') {        //将输入的问号变为感叹号
                t[j] = '!';
                i++;
                j++;
                continue;
            }
    
            if (s[i] != 'I') {        //将除了I的大写变小写
                t[j] = tolower(s[i]);
                i++;
                j++;
            }
            else {
                t[j] = s[i];    //将s串的非空或者单个空格给到t串,之后分别+1进行下一轮输入
                j++;
                i++;
            }
        }
    }
    
    //遍历t并一顿操作后输出,主要把I,me变成you; can you 换成 I can
    void print(char t[], int &j) {
        while (t[j] != '\0') {
            //独立的I,意味着左右均是分隔符
            if (t[j] == 'I' && (j == 0 || isIndependent(t[j - 1])) && isIndependent(t[j + 1])) {
                cout << "you";
                j++;
                continue;
            }
            //独立的me
            if (t[j] == 'm'&&t[j + 1] == 'e' && (j == 0 || isIndependent(t[j - 1])) && isIndependent(t[j + 2])) {
                cout << "you";
                j += 2;
                continue;
            }
    
            //独立的can you
            if (isCanyou(t, j)) {
                cout << "I can";
                j += 7;
                continue;
            }
    
            //如果是标点前的空格就不输出
            if (t[j] == ' '&&isIndependent(t[j + 1])) {
                j++;
                continue;
            }
            cout << t[j];
            j++;
        }
    }
    View Code

    其实做题过程还是挺难受的,经常自己是各种错误出来,但是在bug过程又是超级无敌枯燥和烦闷,明明就是差一点点就可以和答案相同了,但是就是找不到那个小bug在哪里,哎。应该是自己的心态还不够静,静下心来做的时候就会一切好像从容了许多。希望自己戒骄戒躁,静心明阔。

    关于上次博客定下来的目标(多多动手编程),自己觉得还是没有达到,感觉自己在一道题上的时间花太多了。

    接下来目标就继续多动手编程实践,同时缩短自己每道编程题的时间。

    over.

  • 相关阅读:
    time 模块学习
    day 14 自定义模块,常用模块 time .datetime ,time 模块
    day 13 课后作业
    day 12 课后作业
    day 11课后作业
    树状数组最值
    hdu 1059 Dividing bitset 多重背包
    XVII Open Cup named after E.V. Pankratiev. XXI Ural Championship
    最长公共子序列板/滚动 N^2
    Uva 10635
  • 原文地址:https://www.cnblogs.com/jyf2018/p/10705591.html
Copyright © 2020-2023  润新知