前言:内容包括:题目,代码实现,大致思路,代码解读
题目:
以上图片来自新浪微博。
本题要求你实现一个稍微更值钱一点的 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
代码实现:
#include #include //判断是否为空格or非字母非数字字符 int Judge(char p) { if ((p >= 'A' && p = 'a' && p = '0' && p I can、I could
I 和 me 换成 you
在字符数组中一个字符一个字符的对应can you、could you ,I , me
对应之后,不打印can you、could you ,而是打印I can、I could
不打印I , me,而是打印you
若是字符数组中没有完整连续对应上述这些内容,则正常一个一个输出字符
若是完整连续对应上了,在替换打印后,需要要打印can you,could you,I , me之后剩下的所有字符
代码解读
主体部分
int main() { int n = 0; scanf("%d", &n); getchar();//读取数字之后的换行符\n char arr[1001] = { 0 }; int i = 0; for (i = 0; i ! ReplacePrint(arr);//替换can you、could you,I , me并输出已调整好只需替换某些内容的字符串 printf("\n"); } return 0; }
使用get读取带有空格的字符串,,注意需要使用getchar读取\n
函数部分
part 1 删除多余空格
void DelBlank(char arr[], int len) { int i = 0; for (i = 0; i
空格分为:字符串开头处的空格非开头处的空格
非开头处空格的处理:
遍历整个字符数组,若是当前元素是空格,且进一步判断是需要删除的空格,则使用覆盖法,用它后面的人来覆盖它,即此空格后面的所有元素都往前移动一位
注意:由于存在连续空格的情况,即检查出当前元素是空格,使用覆盖法,这个空格位置覆盖上来的又是一个空格,不能直接++,跳过这个已经检查过的位置,判断下一个位置,而是需要先--,这样就又能重新判断这个被覆盖上新值的位置是否仍为空格
a. 判断出当前元素是空格,下一步就是判断这个空格是否需要删除
一个需要删除的空格的条件:它后面的一个元素不是字母,不是数字,即它后面的元素是非字母非数字字符
Judge函数就是判断一个元素是否为非字母非数字字符,返回值为1表示此元素是非字母非数字字符,返回0表示此元素是数字或者字母
开头处空格的处理:
开头处空格比较特殊,都需要删除,而上面所提的删除空格的代码执行的条件是当前空格后面的一个元素需要是非数字非字母字符
而开头处的空格,它后面的一个元素可能是字母,故而不能满足这个条件,若是它两统统都使用着一个删除空格的代码,则肯定是行不通的
我们另外设计一个专门删除开头处的空格的代码,只要开头处(即字符数组的首元素arr[0])是空格,我们就会删除掉这个空格:
if (arr[0] == ' ') { int j = 0; for (j = 0; j
part 2 大写转小写
//大写转小写 void Tolower(char arr[], int len) { int i = 0; for (i = 0; i
遍历整个字符数组,使用tolower函数将大写字母转成小写字母
tolower函数的头文件:
#include
part 3 ?->!
void Change(char arr[], int len) { int i = 0; for (i = 0; i
part 4 输出已经调整好的只需替换某些内容的字符串
//替换并打印最终结果 void ReplacePrint(char arr[]) { printf("AI: "); int i = 0; for (i = 0; i
在字符数组中若不能找到完整连续的can you,could you, I ,me,则一个字符一个字符地输出内容
这是无需替换的正常字符
若是字符数组中能找到完整连续的can you, could you ,I me,则打印I can、I could,you,代替can you, could you ,I me的打印
判断完整连续的独立can you:
can you可以出现在字符串的开头/末尾/中间
独立(隔开)can you: 分为前和后两部分,就像两条线将can you 围住
前一条线: 字符c的下标是0(can you 出现在开头) 或者 字符c的前一个元素是空格(can you 出现在字符串中)
后一条线: 字符u的后一个元素是空格or标点符号or \0
could you ,I me的独立判断同上