赞
踩
以上图片来自新浪微博。
本题要求你实现一个稍微更值钱一点的 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
封装的函数比较多,写的代码也很长,不过应该更好理解。
测试点0占10分,应该是字母转小写的问题,一开始我整道题只得了1分(写了那么久还只是1分崩溃了...),后面我才发现我理解错了”把原文中所有大写英文字母变成小写,除了 I“这句话。意思是句子中本来是大写的"I"就不需要转小写了,比如样例6中的二个单词是"Is",并不需要转成"is",我还以为只有独立的I需要大写...改过来后就15分了。
不确定自己的独立是否实现可以试试:输入“can youI”正确输出为"can youI"、输入“meI”正确输出为"meI"、输入“II”正确输出为"II"。
测试点4应该是题目要求4和要求5的先后顺序的问题,我是通过先完成要求5,再完成要求4解决的。
比如输入"can me”,如果先实现要求5,变为"can you",再实现要求4会变成"I can",但是这样是错的,正确的输出是"can you"。
- #include<iostream>
- #include<string>
- using namespace std;
-
- //把原文中所有大写英文字母变成小写,除了 I
- void letterLower(string& str)
- {
- for (int i = 0; i < str.size(); i++)
- {
- if (str[i] >= 'A' && str[i] <= 'Z' && str[i] != 'I')
- {
- str[i] += 32;
- }
- }
- }
-
- //消除多余空格
- void delSpace(string& str)
- {
- //把行首的空格全部删掉
- while (str.front() == ' ')
- {
- str.erase(0, 1);
- if (str.size() == 0)
- return;
- }
- //把行尾的空格全部删掉
- while (str.back() == ' ')
- {
- str.pop_back();
- }
-
- //把相邻单词间的多个空格换成 1 个空格
- int pos = 0;
- while (pos < str.size() - 1)
- {
- if (str[pos] == ' ' && str[pos + 1] == ' ')
- {
- str.erase(pos, 1);
- continue;
- }
- pos++;
- }
-
- //把标点符号前面的空格删掉
- for (int i = 0; i < str.size() - 1; i++)
- {
- if (str[i] == ' ')
- {
- //除了大写I、小写字母、数字以外的都是标点符号
- if (str[i + 1] == 'I'|| (str[i + 1] >= 'a' && str[i + 1] <= 'z')|| (str[i + 1] >= '0' && str[i + 1] <= '9'))
- continue;//如果不是标点符号,就不删除
- str.erase(i, 1);
- }
- }
- }
-
- //把原文中所有的问号 ? 换成惊叹号 !
- void changeQues(string& str)
- {
- for (int i = 0; i < str.size(); i++)
- {
- if (str[i] == '?')
- str[i] = '!';
- }
- }
-
- //把原文中所有独立的 can you、could you 对应地换成 I can、I could—— 这里“独立”是指被空格或标点符号分隔开的单词
- void answer(string& str)
- {
- int pos = 0;//从头开始处理can you
- while (pos < str.size())
- {
- int findpos = str.find("can you", pos);
- if (findpos == -1)//如果找不到就结束循环
- break;
-
- if (findpos == 0)//如果can you在句子开头
- {
- if (str.size() == 7)//如果句子只是can you,为了防止越界,应该结束循环
- {
- str.replace(findpos, 7, "I can");
- break;
- }
- else if (!(str[findpos + 7] >= 'a' && str[findpos + 7] <= 'z') && !(str[findpos + 7] >= '0' && str[findpos + 7] <= '9') && str[findpos + 7] != 'I' && str[findpos + 7] != 'B')
- {
- str.replace(findpos, 7, "I can");
- }
- pos++;
- continue;
- }
-
- //"can you"出现在最后
- if (findpos + 7 == str.size() && !(str[findpos - 1] >= 'a' && str[findpos - 1] <= 'z') && !(str[findpos - 1] >= '0' && str[findpos - 1] <= '9') && str[findpos - 1] != 'I' && str[findpos - 1] != 'B')
- {
- str.replace(findpos, 7, "I can");
- break;//防止下面代码的越界访问
- }
-
- if ((str[findpos + 7] >= 'a' && str[findpos + 7] <= 'z') || (str[findpos - 1] >= 'a' && str[findpos - 1] <= 'z'))//如果can you前后是小写字母
- {
- pos++;//继续从后一位找
- continue;
- }
- if ((str[findpos + 7] >= '0' && str[findpos + 7] <= '9') || (str[findpos - 1] >= '0' && str[findpos - 1] <= '9'))//如果can you前面或后面是数字
- {
- pos++;//继续从后一位找
- continue;
- }
- if ((str[findpos + 7] == 'I') || (str[findpos - 1] == 'I'))//如果can you前后是大写I
- {
- pos++;//继续从后一位找
- continue;
- }
- if (str[findpos + 7] == 'B')//如果you后是标记用的大写字母B
- {
- pos++;//继续从后一位找
- continue;
- }
- //如果都不是,说明是独立的can you
- str.replace(findpos, 7, "I can");
- pos++;
- }
-
- pos = 0;//从第一位开始处理could you
- while (pos < str.size())
- {
- int findpos = str.find("could you", pos);
- if (findpos == -1)//如果找不到
- break;
-
- if (findpos == 0)//如果could you在句子开头
- {
- if (str.size() == 9)//如果句子只是could you,为了防止越界,应该结束循环
- {
- str.replace(findpos, 9, "I could");
- break;
- }
- else if (!(str[findpos + 9] >= 'a' && str[findpos + 9] <= 'z') && !(str[findpos + 9] >= '0' && str[findpos + 9] <= '9') && str[findpos + 9] != 'I' && str[findpos + 9] != 'B')
- {
- str.replace(findpos, 9, "I could");
- }
- pos++;
- continue;
- }
-
- if (findpos + 9 == str.size() && !(str[findpos - 1] >= 'a' && str[findpos - 1] <= 'z') && !(str[findpos - 1] >= '0' && str[findpos - 1] <= '9') && str[findpos - 1] != 'I' && str[findpos + 9] != 'B')//"could you"出现在最后
- {
- str.replace(findpos, 9, "I could");
- break;
- }
-
- if ((str[findpos + 9] >= 'a' && str[findpos + 9] <= 'z') || (str[findpos - 1] >= 'a' && str[findpos - 1] <= 'z'))//如果could you前面或后面是小写字母
- {
- pos++;//继续从后一位找
- continue;
- }
- if ((str[findpos + 9] >= '0' && str[findpos + 9] <= '9') || (str[findpos - 1] >= '0' && str[findpos - 1] <= '9'))//如果could you前面或后面是数字
- {
- pos++;//继续从后一位找
- continue;
- }
- if ((str[findpos + 9] == 'I') || (str[findpos - 1] == 'I'))//如果could you前后是大写I
- {
- pos++;//继续从后一位找
- continue;
- }
- if (str[findpos + 9] == 'B') //you不能标记后的youB
- {
- pos++;//继续从后一位找
- continue;
- }
- //如果都不是,说明是独立的could you
- str.replace(findpos, 9, "I could");
- pos++;
- }
- }
-
- //把原文中所有独立的 I 和 me 换成 you
- //在这暂时先换成youB,方便和can you,could you的you区分开来
- void changePerson(string& str)//切换人称
- {
- int pos = 0;//从头开始处理独立的me
- while (pos < str.size())
- {
- int findpos = str.find("me", pos);
- if (findpos == -1)//如果找不到
- break;
-
- if (findpos == 0)//防止越界,单独处理
- {
- if (str.size() == 2)//句子只是me
- {
- str.replace(findpos, 2, "youB");
- break;
- }
- else if(!(str[findpos + 2] >= 'a' && str[findpos + 2] <= 'z') && !(str[findpos + 2] >= '0' && str[findpos + 2] <= '9') && str[findpos + 2] != 'I')
- str.replace(findpos, 2, "youB");
-
- pos++;
- continue;
- }
-
- if (findpos + 2 == str.size() && !(str[findpos - 1] >= 'a' && str[findpos - 1] <= 'z') && !(str[findpos - 1] >= '0' && str[findpos - 1] <= '9') && str[findpos - 1] != 'I')//"me"出现在最后
- {
- str.replace(findpos, 2, "youB");
- break;
- }
- if ((str[findpos + 2] >= 'a' && str[findpos + 2] <= 'z') || (str[findpos - 1] >= 'a' && str[findpos - 1] <= 'z'))//如果me前面或后面是小写字母
- {
- pos++;//继续从后一位找
- continue;
- }
- if ((str[findpos + 2] >= '0' && str[findpos + 2] <= '9') || (str[findpos - 1] >= '0' && str[findpos - 1] <= '9'))//如果me前面或后面是数字
- {
- pos++;//继续从后一位找
- continue;
- }
- if ((str[findpos + 2] == 'I') || (str[findpos - 1] == 'I'))//如果me前后是大写I
- {
- pos++;//继续从后一位找
- continue;
- }
- //如果都不是,说明是独立的me
- str.replace(findpos, 2, "youB");
- pos++;
- }
-
- pos = 0;//从头开始处理独立的I
- while (pos < str.size())
- {
- int findpos = str.find("I", pos);
-
- if (findpos == -1)
- break;
-
- if (findpos == 0)//防止越界,单独处理
- {
- if (str.size() == 1)//句子只是I
- {
- str.replace(findpos, 1, "youB");
- break;
- }
- else if (!(str[findpos + 1] >= 'a' && str[findpos + 1] <= 'z') && !(str[findpos + 1] >= '0' && str[findpos + 1] <= '9') && str[findpos + 1] != 'I')
- str.replace(findpos, 1, "youB");
-
- pos++;
- continue;
- }
-
- if (findpos + 1 == str.size() && !(str[findpos - 1] >= '0' && str[findpos - 1] <= '9') && !(str[findpos - 1] >= 'a' && str[findpos - 1] <= 'z') && str[findpos - 1] != 'I')
- {
- str.replace(findpos, 1, "youB");
- break;
- }
- if ((str[findpos - 1] >= '0' && str[findpos - 1] <= '9') || (str[findpos + 1] >= '0' && str[findpos + 1] <= '9'))
- {
- pos++;
- continue;
- }
- if ((str[findpos - 1] >= 'a' && str[findpos - 1] <= 'z') || (str[findpos + 1] >= 'a' && str[findpos + 1] <= 'z'))
- {
- pos++;
- continue;
- }
- if (str[findpos - 1] == 'I' || (str[findpos + 1] == 'I'))
- {
- pos++;
- continue;
- }
- //代码走到这还没continue,说明独立
- str.replace(findpos, 1, "youB");
- pos++;
- }
- }
-
- void eraseB(string& str)
- {
- for (int i = 0; i < str.size(); i++)
- {
- if (str[i] == 'B')
- str.erase(i, 1);
- }
- }
-
-
- void AI(string& str)
- {
- cout << "AI: ";
- changeQues(str);
- letterLower(str);
- delSpace(str);
- changePerson(str);
- answer(str);
- eraseB(str);//将标记用的B删除
- }
-
- int main()
- {
- int n; cin >> n;
- getchar();
-
- while (n--)
- {
- string str;
- getline(cin, str);
- cout << str << endl;
- AI(str);
- cout << str << endl;
- }
-
- return 0;
- }

真的写的好长,这题我也写了很久(一整个晚上),在大学里写没写出来,现在放寒假了从头开始写过...
水平不高,如有不正确的地方,欢迎大家在评论区指正^_^
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。