PTA L1-064 估值一亿的AI核心代码(详解)

这篇具有很好参考价值的文章主要介绍了PTA L1-064 估值一亿的AI核心代码(详解)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言:内容包括:题目,代码实现,大致思路,代码解读

题目:

pta l1-064,PTA,人工智能

以上图片来自新浪微博。

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

  • 无论用户说什么,首先把对方说的话在一行中原样打印出来;
  • 消除原文中多余空格:把相邻单词间的多个空格换成 1 个空格,把行首尾的空格全部删掉,把标点符号前面的空格删掉;
  • 把原文中所有大写英文字母变成小写,除了 I
  • 把原文中所有独立的 can youcould you 对应地换成 I canI 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<stdio.h>
#include<ctype.h>
//判断是否为空格or非字母非数字字符
int Judge(char p)
{
	if ((p >= 'A' && p <= 'Z') || (p >= 'a' && p <= 'z') || (p >= '0' && p <= '9'))
	{
		return 0;
	}
	else
	{
		return 1;
	}
}

//去除空格
void DelBlank(char arr[], int len)
{
	int i = 0;
	for (i = 0; i < len; i++)
	{
		//处理开头的空格
		if (arr[0] == ' ')
		{
			int j = 0;
			for (j = 0; j < len; j++)
			{
				arr[j] = arr[j + 1];
			}
		}

		if (arr[i] == ' ')
		{
			int flag = Judge(arr[i + 1]);
			if (flag == 1)
			{
				int k = 0;
				for (k = i; k < len; k++)
				{
					arr[k] = arr[k + 1];
				}
				i--;
			}
		}
	}
}

//大写转小写
void Tolower(char arr[], int len)
{
	int i = 0;
	for (i = 0; i < len; i++)
	{
		if (arr[i] != 'I')
		{
			arr[i] = tolower(arr[i]);
		}
	}
}

//替换并打印最终结果
void ReplacePrint(char arr[])
{
	printf("AI: ");

	int i = 0;
	for (i = 0; i < strlen(arr); i++)
	{
		if ((arr[i] == 'c' && arr[i + 1] == 'a' && arr[i + 2] == 'n' && arr[i + 3] == ' ' && arr[i + 4] == 'y' && arr[i + 5] == 'o' && arr[i + 6] == 'u') && (i == 0 || arr[i - 1] == ' ') && (arr[i + 7] == ' ' || arr[i + 7] == '\0' || Judge(arr[i + 7])))
		{
			printf("I can");
			i += 6;
		}
		else if ((arr[i] == 'c' && arr[i + 1] == 'o' && arr[i + 2] == 'u' && arr[i + 3] == 'l' && arr[i + 4] == 'd' && arr[i + 5] == ' ' && arr[i + 6] == 'y' && arr[i + 7] == 'o' && arr[i + 8] == 'u') && (i == 0 || arr[i - 1] == ' ') && (arr[i + 9] == ' ' || arr[i + 9] == '\0' || Judge(arr[i + 9])))
		{
			printf("I could");
			i += 8;
		}
		else if (arr[i] == 'I' && (i == 0 || arr[i - 1] == ' ') && (arr[i + 1] == ' ' || arr[i + 1] == '\0' || Judge(arr[i + 1])))
		{
			printf("you");
		}
		else if ((arr[i] == 'm' && arr[i + 1] == 'e') && (i == 0 || arr[i - 1] == ' ') && (arr[i + 2] == ' ' || arr[i + 2] == '\0' || Judge(arr[i + 2])))
		{
			printf("you");
			i += 1;
		}
		else
		{
			printf("%c", arr[i]);
		}
	}
}

void Change(char arr[], int len)
{
	int i = 0;
	for (i = 0; i < len; i++)
	{
		if (arr[i] == '?')
		{
			arr[i] = '!';
		}
	}
}

int main()
{
	int n = 0;
	scanf("%d", &n);
	getchar();
	char arr[1001] = { 0 };
	int i = 0;
	for (i = 0; i < n; i++)
	{
		gets(arr);
		printf("%s\n", arr);
		int len = strlen(arr);
		DelBlank(arr, len);
		Tolower(arr, len);
		Change(arr, len);
		ReplacePrint(arr);
		printf("\n");
	}
	return 0;
}

大致思路:

1 去除空格 : 分两种空格 

 a. 不在开头的空格

遍历字符数组,当发现当前元素是一个空格,需要判断这个元素后面的另一个元素是否为空格or非数字非字母字符,若是,则需要消除多余空格,操作是覆盖法,让这个为空格的元素的后面的所有元素都往前挪一个位置,构成覆盖效果

比如:Hello ?

?前面是一个空格,这种空格是需要被删除的,即一个不需要删除的空格的后面可以是字母,数字,需要删除的空格它的后面是非数字非字母字符,空格

show me 5:第一个空格后面是字母,合法,第二个空格后面是数字,合法,这些空格都不需要删除

Hello ?        这个空格的后面是非数字非字母字符,非法,此空格需要删除

b. 在最开头的空格:可能是一个or多个

 无论是一个or多个空格出现在最开头我们都需要全部消除,若是存在多个空格且最后一个空格后面紧跟着的是字母,则a中所提的消除空格的代码不会执行,故而我们要将出现在开头的空格的消除单独再使用这个覆盖法:让这个为空格的元素的后面的所有元素都往前挪一个位置

2 大写转小写

遍历整个字符数组,所有大写英文字母变成小写,除了 I

可以使用库函数tolower

3 ?变成!

4 替换独立的 can youcould you ->I canI could

        I 和 me 换成 you

在字符数组中一个字符一个字符的对应can youcould you ,I , me

对应之后,不打印can youcould you ,而是打印I canI 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 < n; i++)
	{
		gets(arr);
		printf("%s\n", arr);
		int len = strlen(arr);
		DelBlank(arr, len);//删除多余空格
		Tolower(arr, len);//大写转成小写
		Change(arr, len);//?->!
		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 < len; i++)
	{
		//处理开头的空格
		if (arr[0] == ' ')
		{
			int j = 0;
			for (j = 0; j < len; j++)
			{
				arr[j] = arr[j + 1];
			}
		}

		if (arr[i] == ' ')
		{
			int flag = Judge(arr[i + 1]);
			if (flag == 1)
			{
				int k = 0;
				for (k = i; k < len; k++)
				{
					arr[k] = arr[k + 1];
				}
				i--;//覆盖掉当前为空格的元素后,需要i--,因为在循环中下一步就是执行i++,先退一步,再前进一步==原地不动,就能再次判断这个位置是否覆盖的新值仍为空格
			}
		}
	}
}

空格分为:字符串开头处的空格非开头处的空格

非开头处空格的处理:

遍历整个字符数组,若是当前元素是空格,且进一步判断是需要删除的空格,则使用覆盖法,用它后面的人来覆盖它,即此空格后面的所有元素都往前移动一位

注意:由于存在连续空格的情况,即检查出当前元素是空格,使用覆盖法,这个空格位置覆盖上来的又是一个空格,不能直接++,跳过这个已经检查过的位置,判断下一个位置,而是需要先--,这样就又能重新判断这个被覆盖上新值的位置是否仍为空格

a. 判断出当前元素是空格,下一步就是判断这个空格是否需要删除

一个需要删除的空格的条件:它后面的一个元素不是字母,不是数字,即它后面的元素是非字母非数字字符

Judge函数就是判断一个元素是否为非字母非数字字符,返回值为1表示此元素是非字母非数字字符,返回0表示此元素是数字或者字母

开头处空格的处理:

开头处空格比较特殊,都需要删除,而上面所提的删除空格的代码执行的条件是当前空格后面的一个元素需要是非数字非字母字符

而开头处的空格,它后面的一个元素可能是字母,故而不能满足这个条件,若是它两统统都使用着一个删除空格的代码,则肯定是行不通的

我们另外设计一个专门删除开头处的空格的代码,只要开头处(即字符数组的首元素arr[0])是空格,我们就会删除掉这个空格:

        if (arr[0] == ' ')
		{
			int j = 0;
			for (j = 0; j < len; j++)
			{
				arr[j] = arr[j + 1];
			}
		}

part 2 大写转小写

//大写转小写
void Tolower(char arr[], int len)
{
	int i = 0;
	for (i = 0; i < len; i++)
	{
		if (arr[i] != 'I')
		{
			arr[i] = tolower(arr[i]);
		}
	}
}

遍历整个字符数组,使用tolower函数将大写字母转成小写字母

tolower函数的头文件:

#include <ctype.h>

part 3 ?->!

void Change(char arr[], int len)
{
	int i = 0;
	for (i = 0; i < len; i++)
	{
		if (arr[i] == '?')
		{
			arr[i] = '!';
		}
	}
}

part 4 输出已经调整好的只需替换某些内容的字符串

//替换并打印最终结果
void ReplacePrint(char arr[])
{
	printf("AI: ");

	int i = 0;
	for (i = 0; i < strlen(arr); i++)
	{
		if ((arr[i] == 'c' && arr[i + 1] == 'a' && arr[i + 2] == 'n' && arr[i + 3] == ' ' && arr[i + 4] == 'y' && arr[i + 5] == 'o' && arr[i + 6] == 'u') && (i == 0 || arr[i - 1] == ' ') && (arr[i + 7] == ' ' || arr[i + 7] == '\0' || Judge(arr[i + 7])))
		{
			printf("I can");
			i += 6;//要打印can you之后的剩余字符,从下标i+=7开始,所以先将i(此时是c的下标)加上6(即u的下标,马上要执行的下一条语句是i++,就能使得i成为can you之后的剩余字符的第一个字符的下标
		}
		else if ((arr[i] == 'c' && arr[i + 1] == 'o' && arr[i + 2] == 'u' && arr[i + 3] == 'l' && arr[i + 4] == 'd' && arr[i + 5] == ' ' && arr[i + 6] == 'y' && arr[i + 7] == 'o' && arr[i + 8] == 'u') && (i == 0 || arr[i - 1] == ' ') && (arr[i + 9] == ' ' || arr[i + 9] == '\0' || Judge(arr[i + 9])))
		{
			printf("I could");
			i += 8;//要打印could you之后的剩余字符,从下标i+=9开始,所以先将i(此时是c的下标)加上8(即u的下标,马上要执行的下一条语句是i++,就能使得i成为could you之后的剩余字符的第一个字符的下标
		}
		else if (arr[i] == 'I' && (i == 0 || arr[i - 1] == ' ') && (arr[i + 1] == ' ' || arr[i + 1] == '\0' || Judge(arr[i + 1])))
		{
			printf("you");
		}
		else if ((arr[i] == 'm' && arr[i + 1] == 'e') && (i == 0 || arr[i - 1] == ' ') && (arr[i + 2] == ' ' || arr[i + 2] == '\0' || Judge(arr[i + 2])))
		{
			printf("you");
			i += 1;//要打印me之后的剩余字符,从下标i+=2开始,所以先将i(此时是c的下标)加上1(即e的下标,马上要执行的下一条语句是i++,就能使得i成为me之后的剩余字符的第一个字符的下标
		}
		else
		{
			printf("%c", arr[i]);
		}
	}
}

在字符数组中若不能找到完整连续的can you,could you, I ,me,则一个字符一个字符地输出内容

这是无需替换的正常字符

若是字符数组中能找到完整连续的can you, could you ,I me,则打印I canI 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的独立判断同上文章来源地址https://www.toymoban.com/news/detail-772343.html

到了这里,关于PTA L1-064 估值一亿的AI核心代码(详解)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • PTA L1-025 正整数A+B(详解)

    前言:本期是关于正整数A+B的详解,内容包括四大模块:题目,代码实现,大致思路,代码解读,今天你c了吗?   题的目标很简单,就是求两个正整数 A 和 B 的和,其中 A 和 B 都在区间[1,1000]。稍微有点麻烦的是,输入并不保证是两个正整数。 输入格式: 输入在一行给出

    2023年04月21日
    浏览(40)
  • 【2023团体程序设计天梯赛CCCC】GPLT2023,L1~L2部分(PTA,L1-089~L1-096,L2-045~L2-048)题解代码&复盘

    概要 L1部分:L1-089~L1-096 L2部分:L2-045~L2-048 L3部分:L3-033~L3-036 L1-089 最好的文档 5 L1-090 什么是机器学习 5 L1-091 程序员买包子 10 L1-092 进化论 10 L1-093 猜帽子游戏 15 L1-094 剪切粘贴 15 L1-095 分寝室 20 L1-096 谁管谁叫爹 20 L2-045 堆宝塔 25 L2-046 天梯赛的赛场安排 L2-047 锦标赛 25 L2-048

    2024年02月01日
    浏览(44)
  • L1-095 分寝室PTA

    学校新建了宿舍楼,共有 n 间寝室。等待分配的学生中,有女生 n0​ 位、男生 n1​ 位。所有待分配的学生都必须分到一间寝室。所有的寝室都要分出去,最后不能有寝室留空。 现请你写程序完成寝室的自动分配。分配规则如下: 男女生不能混住; 不允许单人住一间寝

    2024年02月10日
    浏览(44)
  • PTA L1-095 分寝室 (20 分)

    学校新建了宿舍楼,共有 n n n 间寝室。等待分配的学生中,有女生 n 0 n_0 n 0 ​ ​ 位、男生 n 1 n_1 n 1 ​ ​位。所有待分配的学生都必须分到一间寝室。所有的寝室都要分出去,最后不能有寝室留空。 现请你写程序完成寝室的自动分配。分配规则如下: 男女生不能混住; 不

    2023年04月23日
    浏览(37)
  • 【PTA】L1-059 敲笨钟(C++)

    题目链接:L1-059 敲笨钟 - 团体程序设计天梯赛-练习集 (pintia.cn)  题目要求:  输入格式: 输出格式: 输入样例: 输出样例: 思路:  代码: 测试结果: 微博上有个自称“大笨钟V”的家伙,每天敲钟催促码农们爱惜身体早点睡觉。为了增加敲钟的趣味性,还会糟改几句古

    2024年04月11日
    浏览(74)
  • 【PTA】L1-039 古风排版(C++)

    题目链接:L1-039 古风排版 - 团体程序设计天梯赛-练习集 (pintia.cn)  目录: 题目要求: 输入格式: 输出格式: 输入样例: 输出样例: 思路: 代码: 测试结果: ​编辑  中国的古人写文字,是从右向左竖向排版的。本题就请你编写程序,把一段文字按古风排版。 输入在第

    2024年03月26日
    浏览(93)
  • 【PTA】L1-043 阅览室(C++)

    题目链接:L1-043 阅览室 - 团体程序设计天梯赛-练习集 (pintia.cn)  目录: 题目要求: 输入格式: 输出格式: 输入样例: 输出样例:  思路: 代码:; 测试结果: 天梯图书阅览室请你编写一个简单的图书借阅统计程序。当读者借书时,管理员输入书号并按下 S 键,程序开始

    2024年04月15日
    浏览(81)
  • 2023 PTA天梯赛补题(L1 & L2)

    输入输出题 输入输出题 k == n 和 k == m 分别输出,题目怎么说就怎么做 判断一下c 等于a + b还是a*b或者都不是,分别按要求输出 针对每一群玩游戏的宝宝,枚举判断一下就好了 写的有点烦,基本就是一步一步模拟,思路在注释里写了 枚举分配方案,代码中a代表女生寝室的数

    2024年02月03日
    浏览(40)
  • PTA——L1-023 输出GPLT(c语言)

    给定一个长度不超过10000的、仅由英文字母构成的字符串。请将字符重新调整顺序,按 GPLTGPLT.... 这样的顺序输出,并忽略其它字符。当然,四种字符(不区分大小写)的个数不一定是一样多的,若某种字符已经输出完,则余下的字符仍按 GPLT 的顺序打印,直到所有字符都被输

    2024年02月13日
    浏览(35)
  • PTA L1-048 矩阵A乘以B

    前言:内容包括四大模块:题目,代码实现,大致思路,代码解读 给定两个矩阵A和B,要求你计算它们的乘积矩阵AB。需要注意的是,只有规模匹配的矩阵才可以相乘。即若A有Ra​行、Ca​列,B有Rb​行、Cb​列,则只有Ca​与Rb​相等时,两个矩阵才能相乘。 输入格式: 输入

    2024年02月04日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包