当前位置:   article > 正文

L1-064 估值一亿的AI核心代码(C++)

l1-064 估值一亿的ai核心代码

以上图片来自新浪微博。

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

  • 无论用户说什么,首先把对方说的话在一行中原样打印出来;

  • 消除原文中多余空格:把相邻单词间的多个空格换成 1 个空格,把行首尾的空格全部删掉,把标点符号前面的空格删掉;

  • 把原文中所有大写英文字母变成小写,除了 I;

  • 把原文中所有独立的 can you、could you 对应地换成 I can、I could—— 这里“独立”是指被空格或标点符号分隔开的单词;

  • 把原文中所有独立的 I 和 me 换成 you;

  • 把原文中所有的问号 ? 换成惊叹号 !;

  • 在一行中输出替换后的句子作为 AI 的回答。

输入格式:

输入首先在第一行给出不超过 10 的正整数 N,随后 N 行,每行给出一句不超过 1000 个字符的、以回车结尾的用户的对话,对话为非空字符串,仅包括字母、数字、空格、可见的半角标点符号。

输出格式:

按题面要求输出,每个 AI 的回答前要加上 AI: 和一个空格。

输入样例:

  1. 6
  2. Hello ?
  3. Good to chat with you
  4. can you speak Chinese?
  5. Really?
  6. Could you show me 5
  7. What Is this prime? I,don 't know

输出样例:

  1. Hello ?
  2. AI: hello!
  3. Good to chat with you
  4. AI: good to chat with you
  5. can you speak Chinese?
  6. AI: I can speak chinese!
  7. Really?
  8. AI: really!
  9. Could you show me 5
  10. AI: I could show you 5
  11. What Is this prime? I,don 't know
  12. 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"。

  1. #include<iostream>
  2. #include<string>
  3. using namespace std;
  4. //把原文中所有大写英文字母变成小写,除了 I
  5. void letterLower(string& str)
  6. {
  7. for (int i = 0; i < str.size(); i++)
  8. {
  9. if (str[i] >= 'A' && str[i] <= 'Z' && str[i] != 'I')
  10. {
  11. str[i] += 32;
  12. }
  13. }
  14. }
  15. //消除多余空格
  16. void delSpace(string& str)
  17. {
  18. //把行首的空格全部删掉
  19. while (str.front() == ' ')
  20. {
  21. str.erase(0, 1);
  22. if (str.size() == 0)
  23. return;
  24. }
  25. //把行尾的空格全部删掉
  26. while (str.back() == ' ')
  27. {
  28. str.pop_back();
  29. }
  30. //把相邻单词间的多个空格换成 1 个空格
  31. int pos = 0;
  32. while (pos < str.size() - 1)
  33. {
  34. if (str[pos] == ' ' && str[pos + 1] == ' ')
  35. {
  36. str.erase(pos, 1);
  37. continue;
  38. }
  39. pos++;
  40. }
  41. //把标点符号前面的空格删掉
  42. for (int i = 0; i < str.size() - 1; i++)
  43. {
  44. if (str[i] == ' ')
  45. {
  46. //除了大写I、小写字母、数字以外的都是标点符号
  47. if (str[i + 1] == 'I'|| (str[i + 1] >= 'a' && str[i + 1] <= 'z')|| (str[i + 1] >= '0' && str[i + 1] <= '9'))
  48. continue;//如果不是标点符号,就不删除
  49. str.erase(i, 1);
  50. }
  51. }
  52. }
  53. //把原文中所有的问号 ? 换成惊叹号 !
  54. void changeQues(string& str)
  55. {
  56. for (int i = 0; i < str.size(); i++)
  57. {
  58. if (str[i] == '?')
  59. str[i] = '!';
  60. }
  61. }
  62. //把原文中所有独立的 can you、could you 对应地换成 I can、I could—— 这里“独立”是指被空格或标点符号分隔开的单词
  63. void answer(string& str)
  64. {
  65. int pos = 0;//从头开始处理can you
  66. while (pos < str.size())
  67. {
  68. int findpos = str.find("can you", pos);
  69. if (findpos == -1)//如果找不到就结束循环
  70. break;
  71. if (findpos == 0)//如果can you在句子开头
  72. {
  73. if (str.size() == 7)//如果句子只是can you,为了防止越界,应该结束循环
  74. {
  75. str.replace(findpos, 7, "I can");
  76. break;
  77. }
  78. 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')
  79. {
  80. str.replace(findpos, 7, "I can");
  81. }
  82. pos++;
  83. continue;
  84. }
  85. //"can you"出现在最后
  86. 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')
  87. {
  88. str.replace(findpos, 7, "I can");
  89. break;//防止下面代码的越界访问
  90. }
  91. if ((str[findpos + 7] >= 'a' && str[findpos + 7] <= 'z') || (str[findpos - 1] >= 'a' && str[findpos - 1] <= 'z'))//如果can you前后是小写字母
  92. {
  93. pos++;//继续从后一位找
  94. continue;
  95. }
  96. if ((str[findpos + 7] >= '0' && str[findpos + 7] <= '9') || (str[findpos - 1] >= '0' && str[findpos - 1] <= '9'))//如果can you前面或后面是数字
  97. {
  98. pos++;//继续从后一位找
  99. continue;
  100. }
  101. if ((str[findpos + 7] == 'I') || (str[findpos - 1] == 'I'))//如果can you前后是大写I
  102. {
  103. pos++;//继续从后一位找
  104. continue;
  105. }
  106. if (str[findpos + 7] == 'B')//如果you后是标记用的大写字母B
  107. {
  108. pos++;//继续从后一位找
  109. continue;
  110. }
  111. //如果都不是,说明是独立的can you
  112. str.replace(findpos, 7, "I can");
  113. pos++;
  114. }
  115. pos = 0;//从第一位开始处理could you
  116. while (pos < str.size())
  117. {
  118. int findpos = str.find("could you", pos);
  119. if (findpos == -1)//如果找不到
  120. break;
  121. if (findpos == 0)//如果could you在句子开头
  122. {
  123. if (str.size() == 9)//如果句子只是could you,为了防止越界,应该结束循环
  124. {
  125. str.replace(findpos, 9, "I could");
  126. break;
  127. }
  128. 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')
  129. {
  130. str.replace(findpos, 9, "I could");
  131. }
  132. pos++;
  133. continue;
  134. }
  135. 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"出现在最后
  136. {
  137. str.replace(findpos, 9, "I could");
  138. break;
  139. }
  140. if ((str[findpos + 9] >= 'a' && str[findpos + 9] <= 'z') || (str[findpos - 1] >= 'a' && str[findpos - 1] <= 'z'))//如果could you前面或后面是小写字母
  141. {
  142. pos++;//继续从后一位找
  143. continue;
  144. }
  145. if ((str[findpos + 9] >= '0' && str[findpos + 9] <= '9') || (str[findpos - 1] >= '0' && str[findpos - 1] <= '9'))//如果could you前面或后面是数字
  146. {
  147. pos++;//继续从后一位找
  148. continue;
  149. }
  150. if ((str[findpos + 9] == 'I') || (str[findpos - 1] == 'I'))//如果could you前后是大写I
  151. {
  152. pos++;//继续从后一位找
  153. continue;
  154. }
  155. if (str[findpos + 9] == 'B') //you不能标记后的youB
  156. {
  157. pos++;//继续从后一位找
  158. continue;
  159. }
  160. //如果都不是,说明是独立的could you
  161. str.replace(findpos, 9, "I could");
  162. pos++;
  163. }
  164. }
  165. //把原文中所有独立的 I 和 me 换成 you
  166. //在这暂时先换成youB,方便和can you,could you的you区分开来
  167. void changePerson(string& str)//切换人称
  168. {
  169. int pos = 0;//从头开始处理独立的me
  170. while (pos < str.size())
  171. {
  172. int findpos = str.find("me", pos);
  173. if (findpos == -1)//如果找不到
  174. break;
  175. if (findpos == 0)//防止越界,单独处理
  176. {
  177. if (str.size() == 2)//句子只是me
  178. {
  179. str.replace(findpos, 2, "youB");
  180. break;
  181. }
  182. else if(!(str[findpos + 2] >= 'a' && str[findpos + 2] <= 'z') && !(str[findpos + 2] >= '0' && str[findpos + 2] <= '9') && str[findpos + 2] != 'I')
  183. str.replace(findpos, 2, "youB");
  184. pos++;
  185. continue;
  186. }
  187. 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"出现在最后
  188. {
  189. str.replace(findpos, 2, "youB");
  190. break;
  191. }
  192. if ((str[findpos + 2] >= 'a' && str[findpos + 2] <= 'z') || (str[findpos - 1] >= 'a' && str[findpos - 1] <= 'z'))//如果me前面或后面是小写字母
  193. {
  194. pos++;//继续从后一位找
  195. continue;
  196. }
  197. if ((str[findpos + 2] >= '0' && str[findpos + 2] <= '9') || (str[findpos - 1] >= '0' && str[findpos - 1] <= '9'))//如果me前面或后面是数字
  198. {
  199. pos++;//继续从后一位找
  200. continue;
  201. }
  202. if ((str[findpos + 2] == 'I') || (str[findpos - 1] == 'I'))//如果me前后是大写I
  203. {
  204. pos++;//继续从后一位找
  205. continue;
  206. }
  207. //如果都不是,说明是独立的me
  208. str.replace(findpos, 2, "youB");
  209. pos++;
  210. }
  211. pos = 0;//从头开始处理独立的I
  212. while (pos < str.size())
  213. {
  214. int findpos = str.find("I", pos);
  215. if (findpos == -1)
  216. break;
  217. if (findpos == 0)//防止越界,单独处理
  218. {
  219. if (str.size() == 1)//句子只是I
  220. {
  221. str.replace(findpos, 1, "youB");
  222. break;
  223. }
  224. else if (!(str[findpos + 1] >= 'a' && str[findpos + 1] <= 'z') && !(str[findpos + 1] >= '0' && str[findpos + 1] <= '9') && str[findpos + 1] != 'I')
  225. str.replace(findpos, 1, "youB");
  226. pos++;
  227. continue;
  228. }
  229. 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')
  230. {
  231. str.replace(findpos, 1, "youB");
  232. break;
  233. }
  234. if ((str[findpos - 1] >= '0' && str[findpos - 1] <= '9') || (str[findpos + 1] >= '0' && str[findpos + 1] <= '9'))
  235. {
  236. pos++;
  237. continue;
  238. }
  239. if ((str[findpos - 1] >= 'a' && str[findpos - 1] <= 'z') || (str[findpos + 1] >= 'a' && str[findpos + 1] <= 'z'))
  240. {
  241. pos++;
  242. continue;
  243. }
  244. if (str[findpos - 1] == 'I' || (str[findpos + 1] == 'I'))
  245. {
  246. pos++;
  247. continue;
  248. }
  249. //代码走到这还没continue,说明独立
  250. str.replace(findpos, 1, "youB");
  251. pos++;
  252. }
  253. }
  254. void eraseB(string& str)
  255. {
  256. for (int i = 0; i < str.size(); i++)
  257. {
  258. if (str[i] == 'B')
  259. str.erase(i, 1);
  260. }
  261. }
  262. void AI(string& str)
  263. {
  264. cout << "AI: ";
  265. changeQues(str);
  266. letterLower(str);
  267. delSpace(str);
  268. changePerson(str);
  269. answer(str);
  270. eraseB(str);//将标记用的B删除
  271. }
  272. int main()
  273. {
  274. int n; cin >> n;
  275. getchar();
  276. while (n--)
  277. {
  278. string str;
  279. getline(cin, str);
  280. cout << str << endl;
  281. AI(str);
  282. cout << str << endl;
  283. }
  284. return 0;
  285. }

真的写的好长,这题我也写了很久(一整个晚上),在大学里写没写出来,现在放寒假了从头开始写过...

水平不高,如有不正确的地方,欢迎大家在评论区指正^_^

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/277190
推荐阅读
相关标签
  

闽ICP备14008679号