L1-064 估值一亿的AI核心代码
Statement
Metadata
- 作者: 陈越
- 单位: 浙江大学
- 代码长度限制: 16 KB
- 时间限制: 400 ms
- 内存限制: 64 MB
以上图片来自新浪微博。
本题要求你实现一个稍微更值钱一点的 AI 英文问答程序,规则是:
- 无论用户说什么,首先把对方说的话在一行中原样打印出来;
- 消除原文中多余空格:把相邻单词间的多个空格换成 1 个空格,把行首尾的空格全部删掉,把标点符号前面的空格删掉;
- 把原文中所有大写英文字母变成小写,除了
I
; - 把原文中所有独立的
can you
、could you
对应地换成I can
、I could
—— 这里“独立”是指被空格或标点符号分隔开的单词; - 把原文中所有独立的
I
和me
换成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
题意:
给一个字符串
- 无论用户说什么,首先把对方说的话在一行中原样打印出来;
- 消除原文中多余空格:把相邻单词间的多个空格换成
个空格,把行首尾的空格全部删掉,把标点符号前面的空格删掉; - 把原文中所有大写英文字母变成小写,除了
I
; - 把原文中所有独立的
can you
、could you
对应地换成I can
、I could
—— 这里“独立”是指被空格或标点符号分隔开的单词; - 把原文中所有独立的
I
和me
换成you
; - 把原文中所有的问号
?
换成惊叹号!
; - 在一行中输出替换后的句子作为
AI
的回答。
思路:
文本替换。
- 有问题的一点就是要明白这个替换的同时进行的,并没有先后关系。
- 会出问题的点在于第
点:这两个不能有先后顺序的替换,一个可行的方法是先替换成另一种字符. - 譬如
I can
->@ can
,I could
->@ could
,这样加入一步中间状态,那么在第步的时候,就不会替换掉 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