《数据结构》--第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.

猜你喜欢

转载自www.cnblogs.com/jyf2018/p/10705591.html