0.展示PTA总分

单循环结构

嵌套循环

1.本章学习总结

1.1 学习内容总结

1.知道了while语句用于实现循环,且它的适用面更广,它的一般形式是:

2.知道了while语句中的表达式可以是任意合法的表达式,循环体语句可以包含for语句,且使用for语句可以更清晰

3.知道了需要用特殊的数值比如负数或0来作为结束标志应该怎么写

4.知道了fflush()可以清除空格

5.知道了whiledo while 的区别:


1.不同:
while语句是在循环前先判断条件,只有条件满足才会进入循环,如果一开始条件就不满足,则循环一次都不执行;而do-while语句是先执行循环体,后判断循环条件,所以至少会执行一次循环体。
2.相同:
do-while和while语句中的表达式都可以是任意合法的表达式,循环体语句只能是一条语句,使用时都要另外加初始化的部分,循环体语句都必须包含能最终改变条件真假性的操作。

6.知道了break语句continue语句的区别:


1.break结束循环,而continue只是跳过后面语句继续循环。
2.break除了可以终止循环外,还用于switch语句,而continue只能用于循环。

7.了解了在嵌套循环中容易犯的错误就是:

循环初始化语句放错位置,混淆了内外层循环的初始化

8.知道了分支结构中语句只能执行一次,而循环结构中语句可以重复执行多次

9.认识到了三种循环的特色:

一般说来,如果事先给定了循环次数,首选for语句,它看起来最清晰,循环的4个组成部分一目了然;如果循环次数不明确,需要通过其他条件控制循环,通常选用 while语句或do- while语句;如果必须先进入循环,经循环体运算得到循环控制条件后,再判断是否进行下一次循环,使用do- while语句最合适。

10.知道了当题目没有指定输入数据的个数时,需要自己增加循环条件的两种途径:


① 先输入一个正整数n,代表数据的个数,然后再输入n个数据,循环重复n次,属于指定次数的循环,用for语句实现。
② 设定一个特殊数据(伪数据)作为循环的结束标志,由于成绩都是正数,选用个负数作为输入的结束标志。由于循环次数未知,考虑使用 while语句。

1.2 本章学习体会

  • 通过这一段时间的学习,我认识到了循环结构的使用,但是进入这一阶段,我的疑虑越来越多,一个PTA不断改进,可能错误还是不会变,为此我感到很焦虑,我也一直在问别人,看书,看视频,希望可以起到作用。
  • 我还学会了运用printf的输出的调试方式,通过直接输出想要知道的答案,便于找出循环量较大时的问题所在。
  • 在一些嵌套循环但是没有加{}的代码中,我不是很懂对应的条件,一层套一层容易乱。
  • 我的代码量(不包括重复)
代码量(行)
4 241
5 506
6 771
7 842
累计 2360

2.PTA实验作业

2.1 题目名1



梅森数 (20 分)
形如2^​n−1的素数称为梅森数(Mersenne Number)。例如2^​2−1=3、2^​3−1=7都是梅森数。1722年,双目失明的瑞士数学大师欧拉证明了2^31−1=2147483647是一个素数,堪称当时世界上“已知最大素数”的一个记录。
本题要求编写程序,对任一正整数n(n<20),输出所有不超过2^​n−1的梅森数。


2.1.1 数据处理-伪代码

定义一个函数Mer来求2^​n−1的值,
定义i,j来从小到大依次判断,
定义n为输入的正整数,
定义sum来记录2^​n−1的值,
定义flag来控制输出,
定义count来记录梅森数的个数

给count赋初值

输入正整数n(n<20)

if (n == 2) 输出3\n
else
	{
		for i = 2到 i <= n, i++
		{
			此时flag = 1
			调用函数Mer求出sum
			for j = 2到 j < sum, j++
			{
				if (sum % j == 0)
				{
					能整除,不是素数,则令flag = 0
					跳出循环
				}
			}
			if (flag == 1)
			{
				if (sum > 2)
				{
					当flag=1时,即不能被整除,说明是素数且符合梅森数,输出sum的值
					count记录数值加1
				}
			}
		}
		if (count == 0)
		{
			当count记录为0时,即没有梅森数,则输出None\n
		}
	}

定义函数int Mer(主函数调用的形参n)
{
	定义k从小到大依次判断,定义s使一直被乘,定义m用来储存函数结果
	给s赋值2
	给m赋初值2,因为有特殊情况
	if (n == 0)
	{
		如果n为0,则m只能是0
	}
	else if (n == 1)
	{
		如果n为1,则m只能是1
	}
	else
	{
		for k = 2到 k <= n, k++
		{
			算m=2^m,一直到2^n
		}
		令m = m - 1,即相当于2^n-1
	}

	令函数结果m的值返回主函数 
}

2.1.2 代码截图




2.1.3 造测试数据

输入数据 输出数据 说明
6 正常数据
0 None 最小n,输出为空集
2 3 n=2, 只有一个梅森数

2.1.4 PTA提交列表及说明

提交列表说明:


1. 部分正确:sample等价,取最大n时,运用嵌套过多,导致运行超时,n=2, 只有一个梅森数时,未考虑到特殊情况,答案错误
2. 多种错误:i没有从1开始计算,最小n,输出为空集,答案错误,加上前面的错误
3. 部分正确:根据测试点2得出,n==2时只有3,考虑到此特殊情况,测试点2改正确
4. 编译错误:从vs复制到PTA时忘记去掉scanf_s的_s
5. 部分正确:把求sum重新定义一个函数,减少嵌套循环,减少运行时间,测试点1改正确
6. 部分正确:在vs调试后发现,最后判断是否有梅森数的条件语句应该放在else语句内,否则其他也会输出None,导致答案错误
7. 答案正确:在vs调试后发现,n<=1在前面不用再写,否则输出两个None,导致答案错误


2.2 题目名2


查询水果价格 (15 分)
给定四种水果,分别是苹果(apple)、梨(pear)、桔子(orange)、葡萄(grape),单价分别对应为3.00元/公斤、2.50元/公斤、4.10元/公斤、10.20元/公斤。
用户可以输入编号1~4查询对应水果的单价。当连续查询次数超过5次时,程序应自动退出查询;不到5次而用户输入0即退出;输入其他编号,显示价格为0。


2.2.1 数据处理-伪代码

定义一个函数Menu来输出菜单,因为不需要返回,函数类型是void,
定义choice为用户输入的编号,
定义i来从小到大依次判断

调用函数Menu输出菜单

for i = 1到i <= 5, i++
	{
		用户输入choice
		用switch语句判断choice的数值
		{
		如果choice为1:
			输出price = 3.00\n
			跳出循环

		如果choice为2:
			输出price = 2.50\n
			跳出循环

		如果choice为3:
			输出price = 4.10\n
			跳出循环

		如果choice为4:
			输出price = 10.20\n
			跳出循环

		如果choice为0:
			直接跳出循环

		default:
			剩余的,即在输入不合法时需要输出price = 0.00\n
			跳出循环

		}
		if (choice == 0)
		{
			返回,退出for循环
		}

	}
定义函数void Menu()
{
	菜单内容
}

2.2.2 代码截图



2.2.3 造测试数据

输入数据 输出数据 说明
3 -1 0 2 不到5次而用户输入0,程序结束
1 2 3 3 4 4 5 6 7 8 连续查询次数超过5次时,程序自动退出查询
7 输入其他编号,显示价格为0

2.2.4 PTA提交列表及说明

提交列表说明:


1. 部分正确:输入选择后直接跳过switch语句,未执行中间过程
2. 编译错误:从vs复制到PTA时忘记去掉scanf_s的_s
3. 部分正确:由于前面的switch语句未执行,改变后运用自定义函数PutPrice函数,但仍然未执行输出价格的程序
4. 部分正确:运用for语句,令i从小到大依次判断
5. 部分正确:输入一个数后,不能输入下一个数
6. 部分正确:仔细阅读代码后,发现%d后vs中自动打出一个空格,导致不能输入下一个数
7. 部分正确:在输入不合法时需要输出price = 0.00,审题不仔细,应该加default
8. 答案正确:最后需要加if语句,因为当choice为0时,前面只能退出switch循环,不能退出for循环,还会继续for循环


2.3 题目名3


打印九九口诀表 (15 分)
下面是一个完整的下三角九九口诀表:

1*1=1   
1*2=2   2*2=4   
1*3=3   2*3=6   3*3=9   
1*4=4   2*4=8   3*4=12  4*4=16  
1*5=5   2*5=10  3*5=15  4*5=20  5*5=25  
1*6=6   2*6=12  3*6=18  4*6=24  5*6=30  6*6=36  
1*7=7   2*7=14  3*7=21  4*7=28  5*7=35  6*7=42  7*7=49  
1*8=8   2*8=16  3*8=24  4*8=32  5*8=40  6*8=48  7*8=56  8*8=64  
1*9=9   2*9=18  3*9=27  4*9=36  5*9=45  6*9=54  7*9=63  8*9=72  9*9=81  
本题要求对任意给定的一位正整数N,输出从1*1到N*N的部分口诀表。


2.3.1 数据处理-伪代码


定义正整数N,让乘法口诀表输出的为1*1到N*N的部分,
定义第一个乘数num1,
定义第二个乘数num2,
定义两个数的乘积 result

输入正整数N

for num1 = 1到num1 <= N, num1++
	{
		for num2 = 1到 num2 <= num1,num2++
		{

			求出结果result
			按照要求格式输出 %d*%d=%-4d  
		}
		输出换行
	}


2.3.2 代码截图

2.3.3 造测试数据

输入数据 输出数据 说明
4 正常数据
10 大于9*9,不对齐
0 等于0时,无输出

2.3.4 PTA提交列表及说明

提交列表说明:


1. 部分正确:输出时格式不对,变成矩形输出
2. 多种错误:换行用i++来换行,即如果=i时,则输出\n,不知道怎么右边要占4位输出
3. 多种错误:改在最后输出\n来换行,但是结果仍然不正确
4. 部分正确:把输出\n提前到for语句中,结束一大轮循环中的一个小循环后则换行
5. 答案正确:%-4d可以使右边占4位,对比结果后发现,第一个乘数和第二个乘数位置反了,将num1和num2换一下

3.代码互评

3.1.1代码截图

赵禹琛同学代码

我的代码

3.1.2代码比较


1. 在禹琛同学的代码中,她运用了flag语句来控制输出,可以更容易地记录当前情况,而我的代码中直接用n来判断,我认为更容易读懂
2. 禹琛同学的代码中运用了两次scanf函数,而我运用了getchar()函数输入并且在while语句中,可以直接循环多次
3. 禹琛同学的代码条件顺序与我相反,但是比较简洁,我应该向她学习


3.2.1代码截图

申超同学代码

我的代码


3.2.2代码比较


1. 申超同学的思路很清晰,在for语句中各种硬币数量增加时可以从x出发,逐渐减少,而我则多想,认为x应该减去前面已有的,虽然申超同学的代码看起来比我的简单,但是在执行过程中,我的代码执行循环次数要比他的少,时间更短,但是我也应该向他学习他的思维方式
2. 申超同学运用的for循环比我的多一层,增加了时间
3. 申超同学的变量名称应该使用驼峰法,那样更具有可读性


posted on 2019-10-20 17:12    阅读(644)  评论(0编辑  收藏  举报

/*
*/