zoukankan      html  css  js  c++  java
  • L1-064 估值一亿的AI核心代码

    PTA原题链接

    • 题目描述

    (图略)

    以上图片来自新浪微博。

    本题要求你实现一个稍微更值钱一点的 AI 英文问答程序,规则是:

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

    实际上只是个字符串替换,显然可以用 C++ 的 regex 库解决,但是我们这里没有这么做。

    1. 观察题目的要求,显然 3 和 6 是可以一起做的;
    2. 对于 2,我们需要除去多余的空格,其实可以所有单词逐个取出,再判断何时添加单个空格。它的好处在于不用关心首尾多余的空格,也不用担心空行的出现;
    3. 先 5 后 4,否则 can you 会被替换成 you can 而不是 I can
    4. 对于 4 要注意 can you,can you ,由于我们把所有单词逐个取出,所以会被分割为 can you,can you 。为了判断方便,我们在处理大小写的时候可以在标点符号前添加空格(即使多余了空格也会在后面的操作中解决),使其可以被分割为 can you ,can you ,从而保证被逐个正确替换;
    5. 最后只要注意防断错误和一些小细节就可以了,代码中的强制类型转换是必要的。
    • AC 代码
    /*
     *lang C++(g++)
     *user 八衛門狸
    */
    #include <iostream>
    #include <algorithm>
    #include <string>
    #include <cctype>
    #include <cstdlib>
    #include <sstream>
    
    using namespace std;
    
    int main()
    {
            string comm;
            int no;
            scanf("%d", &no);
            getchar();
    
            for (int i = 0; i < no; i++) {
                    getline(cin, comm);
                    cout << comm << endl;
                    //转小写,? -> !,每个标点前加一个空格
                    for (int i = 0; i < comm.length(); i++) {
                            if (comm[i] == '?') comm[i] = '!';
                            else if (isupper(comm[i]) && comm[i] != 'I') comm[i] = tolower(comm[i]);
                            if (!isalpha(comm[i]) && !isdigit(comm[i]) && !isspace(comm[i])) {
                                    comm = comm.substr(0, i) + ' ' + comm.substr(i);
                                    i++;
                            }
    
                    }
    
                    stringstream ss(comm);
                    int f = 0;
                    int endline = 1;
                    cout << "AI: ";
                    //由于需要 4 同时判断前后两个单词,故引入 pword 作为当前单词, word 为下一单词
                    string pword, word;
                    ss >> pword;
                    while (1) {
                            //防止最后一个单词不输出
                            if (ss >> word) ;
                            else {
                                    if (endline) endline = 0;
                                    else break;
                            }
    
                            // I -> you, me -> you
                            for (int i = 0; i < pword.length(); i++) {
                                    if (pword[i] == 'I') {
                                            if (i > 0 && (isdigit(pword[i-1]) || isalpha(pword[i-1]))) continue;
                                            else if (i < pword.length()-1 && (isdigit(pword[i+1]) || isalpha(pword[i+1]))) continue;
                                            pword = pword.substr(0, i) + "you" + pword.substr(i+1);
                                    }
                            }
                            for (int i = 0; i < (int)pword.length()-1; i++) {
                                    if (pword[i] == 'm' && pword[i+1] == 'e') {
                                            if (i > 0 && (isdigit(pword[i-1]) || isalpha(pword[i-1]))) continue;
                                            else if (i < pword.length()-2 && (isdigit(pword[i+2]) || isalpha(pword[i+2]))) continue;
                                            pword = pword.substr(0, i) + "you" + pword.substr(i+2);
                                    }
                            }
    
                            // can you -> I can, could you -> I could
                            if (pword.length() >= 3 && pword.substr(pword.length() - 3) == "can" && word == "you") {
                                    pword = pword.substr(0, (int)pword.length() - 3) + "I";
                                    word = "can";
                            } else if (pword.length() >= 5 && pword.substr((int)pword.length() - 5) == "could" && word == "you") {
                                    pword = pword.substr(0, (int)pword.length() - 5) + "I";
                                    word = "could";
    
                            }
    
                            //加空格
                            if ((!isdigit(pword[0]) && !isalpha(pword[0])) || !f) {cout << pword; f = 1;}
                            else cout << ' ' << pword;
    
                            pword = word;
                    }
                    cout << endl;
            }
    
            return 0;
    }
    

    by SDUST weilinfox

    本文地址:https://www.cnblogs.com/weilinfox/p/12545371.html

  • 相关阅读:
    cmb 命令
    一个Cookie登录的示例
    webApp开发流程
    17-8-26-WebApp总结
    通过安装WordPress来搭建lamp开发环境
    Windows修改保存txt文件的默认字符集
    js在客户端创建js可读xml
    eclipse常用快捷键
    Express -api参考
    安装ubuntu kylin时问题解决
  • 原文地址:https://www.cnblogs.com/weilinfox/p/12545371.html
Copyright © 2011-2022 走看看