Skip to content

L1-064 估值一亿的AI核心代码

Statement

Metadata

  • 作者: 陈越
  • 单位: 浙江大学
  • 代码长度限制: 16 KB
  • 时间限制: 400 ms
  • 内存限制: 64 MB

AI.jpg

以上图片来自新浪微博。

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

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

Tutorial

题意:

给一个字符串 s:

  • 无论用户说什么,首先把对方说的话在一行中原样打印出来;
  • 消除原文中多余空格:把相邻单词间的多个空格换成 1 个空格,把行首尾的空格全部删掉,把标点符号前面的空格删掉;
  • 把原文中所有大写英文字母变成小写,除了 I
  • 把原文中所有独立的 can youcould you 对应地换成 I canI could—— 这里“独立”是指被空格或标点符号分隔开的单词;
  • 把原文中所有独立的 Ime 换成 you
  • 把原文中所有的问号 ? 换成惊叹号 !
  • 在一行中输出替换后的句子作为 AI 的回答。

思路:

文本替换。

  • 有问题的一点就是要明白这个替换的同时进行的,并没有先后关系。
  • 会出问题的点在于第 4, 5 点:这两个不能有先后顺序的替换,一个可行的方法是先替换成另一种字符.
  • 譬如 I can -> @ canI could -> @ could,这样加入一步中间状态,那么在第 5 步的时候,就不会替换掉 I can 中的 I,然后最后将 @ 替换回来即可。

Solution

#include <bits/stdc++.h>
using namespace std;
using pSS = pair<string, string>;
#define all(x) x.begin(), x.end()
#define SZ(x) (int(x.size()))
#define fi first
#define se second
#define endl "\n"

bool isPunc(char ch) {
    return !isdigit(ch) && !isalpha(ch) && ch != ' ';
}

bool match(string &s, int l, int r, string &t) {
    if (SZ(t) != r - l + 1 || l < 0 || r >= SZ(s))
        return false;
    for (int i = l, j = 0; i <= r; ++i, ++j) {
        if (s[i] != t[j])
            return false;
    }
    return true;
}

string trim(string &s) {
    while (s.end()[-1] == ' ') s.pop_back();
    reverse(all(s));
    while (s.end()[-1] == ' ') s.pop_back();
    reverse(all(s));
    return s;
}

string delSpace(string &s) {
    string res = "";
    int num = 0;
    for (int i = 0; i < SZ(s); ++i) {
        if (s[i] == ' ') {
            ++num;
        } else {
            if (num && !isPunc(s[i]))
                res += " ";
            res += s[i];
            num = 0;
        }
    }
    return res;
}

string toLower(string &s) {
    for (int i = 0; i < SZ(s); ++i) {
        if (isupper(s[i]) && s[i] != 'I') {
            s[i] = s[i] - 'A' + 'a';
        }
    }
    return s;
}

string change(string &s, vector<pSS> vec) {
    string res = "";
    for (int i = -1; i < SZ(s); ++i) {
        if (i == -1 || isPunc(s[i]) || s[i] == ' ') {
            int ok = 0;
            for (auto &it : vec) {
                int len = SZ(it.fi);
                if (match(s, i + 1, i + len, it.fi) &&
                        (i + len + 1 == SZ(s) || isPunc(s[i + len + 1]) || s[i + len + 1] == ' ')) {
                    if (i != -1)
                        res += s[i];
                    res += it.se;
                    i += len;
                    ok = 1;
                    break;
                }
            }
            if (ok)
                continue;
        }
        if (i != -1)
            res += s[i];
    }
    return res;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int _T;
    cin >> _T;
    string s;
    getline(cin, s);
    while (_T--) {
        getline(cin, s);
        cout << s << endl;
        s = trim(s);
        s = delSpace(s);
        s = toLower(s);
        s = change(s, vector<pSS>({pSS("can you", "@ can"), pSS("could you", "@ could")}));
        s = change(s, vector<pSS>({pSS("I", "you"), pSS("me", "you")}));
        for (int i = 0; i < SZ(s); ++i) {
            if (s[i] == '?')
                s[i] = '!';
            if (s[i] == '@')
                s[i] = 'I';
        }
        cout << "AI: " + s << endl;
    }
    return 0;
}

Last update: May 4, 2022
Back to top