郝啟强
摘要:在新课程背景下,程序算法作为程序设计的灵魂,在培养学生计算思维能力方面的地位和作用越来越突出,可是在程序算法入门教学中,很多学生甚至包括教师都对涉及的程序算法望而却步,因为不好讲,也不太好理解,所以大多停留在编程语言语法和编程工具的介绍上。本文作者结合多年程序设计教学经验,尝试在新课程背景下对初中程序设计算法入门做一些探索,为学生打开程序设计的大门。
关键词:程序设计;计算思维;算法
中图分类号:G434 文献标识码:A 论文编号:1674-2117(2022)01-0033-03
义务教育信息技术学科核心素养之一就是培养计算思维能力,程序设计算法为计算思维的培养提供了很好的诠释。计算思维虽然不等同于程序设计的算法思想,但是二者却是紧密联系的,计算思维是抽象的思维活动,是一种思考方式,而算法作为程序设计的灵魂,则是把这种思维具象化,变成了具体的方法和解决问题的步骤,从而编写出完美的程序代码。在新课程背景下,程序设计编程的地位和作用越来越突出。因此,程序设计入门教学应当从过去单纯地介绍某一门编程语言语法和编程工具,逐步转向培养学生计算思维能力,尝试运用计算思维识别与分析问题,抽象、建模与设计系统性解决方案。为此,笔者结合多年程序设计教学经验,尝试了如下教学策略。
● 从生活中的情境入手——让程序变得有温度
在程序算法入门教学中,教师单纯地就程序说程序,以代码说算法,对学生而言这是一种被动的知识输入,在学生进行知识的建构过程中,教师灌输居多,而非学生主动发现认知,导致程序代码脱离生活实际。如果能创设一个贴近生活的学习情境,通过实际需求呼唤程序算法,并最终转换成程序代码,或许学生更容易入门。因此,教师可以适当地从学生生活中常见的情境入手,让程序更接地气,减少与学生的距离感,让学生消除对程序的陌生感,感受到程序的温度。
1.情境样例——两杯液体互换
例如,两个变量交换数值这一概念,用3行简单的代码(temp=a;a=b;b=temp)就能够实现,可是对初学者而言,可能会有这样的疑惑:为什么会这样写?为什么不能直接写a=b;b=a?在实际教学中,教师可以尝试以生活中两个杯子中的液体互换为例,引发学生思考:有两个杯子,a杯装橙汁,b杯装牛奶,如何完成互换?学生会很容易想到再用一个杯子c(甚至更多杯子)来做过渡,即先将a杯橙汁倒入空的c杯,然后将b杯牛奶倒入a杯,最后把c杯橙汁倒入b杯,从而实现互换。这样通过打比方,帮助学生理解交换过程,然后再过渡到代码编写,水到渠成。
2.情境样例——银行卡安全防护
在讲解While条件循环时,教师可以以为银行设计安全防护为生活实例来展开。密码登录V1.0版本可以设计为if(password = =“123456”),但这只是单次判断;由此引入密码登录V2.0版本,用户登录系统循环检测用户输入密码是否正确,如不正确则重复输入,这是很典型的条件循环;在V3.0版本,还可以加入累加器知识点,对用户输错次数进行统计,每错一次累加器就累加一次,即s=s+1,当错误达到5次,結束用户恶意穷举,跳出循环。这样以实例激发学生学习内驱力,效果会更佳。
● 从不插电的小游戏入手——让程序保持热度
在程序算法入门教学中,枯燥的代码会让学生兴趣减退,所以教师可以考虑在讲一些经典的程序算法时,暂时抛开代码,带着学生做一些不插电的小游戏活动,让学生在游戏中体验相关算法的执行过程,强化对算法的理解。
1.游戏样例——身高体重打擂台
例如,在讲解如何在两个数中找最大的数时,笔者喜欢带学生围绕身高体重的数值打一次擂台,帮助学生体验数的比较过程。即先设置一个擂主,参与游戏的两位学生采用比身高或者体重的方式“打擂”,获胜者荣登宝座,程序代码表达为:
if (max==a) max=a;else max=b;
在学会2个数比大小后,接着思考3个数如何比较大小?同样可以先设擂主,即max=a,b和c分别挑战擂主,就会有2次挑战过程,挑战者挑战成功则换人,否则就不变,故而后面的else max=max可以省略。程序代码如图1所示。
在理解3个数比大小之后,再引导学生思考多个数(如20个数)如何打擂台?不难发现思路跟3个数打擂原理是一样的。但由于挑战者较多,不可能写19行重复的挑战代码,因此可以引入循环和数组来优化代码,程序代码总结如图2所示。
2.游戏样例——排序算法
笔者发现,通过游戏模拟体验,过渡到代码编写,学生是比较容易接受的。例如,在讲解选择和冒泡排序算法时,教师可以网络查找关于排序经典算法系列的舞蹈视频,如匈牙利Sapientia大学的学生别出心裁地将选择、插入、冒泡、希尔、归并、快排等6种经典排序算法编成舞蹈。虽然学生没有这样的舞蹈功底,但是其教学思路与不插电小游戏有着异曲同工之处。具体游戏方法如下:选择5位高矮不一的学生作为待排对象;给5位学生每人发一张白纸,要求写上自己的身高(单位厘米);学生手持写有自己身高的卡片随机站成一排(如图3)。
模拟第1轮排序——确定最高的第1名(如图4)。
第1轮程序描述:为了确定左边第1个位置站的是最高个的同学,从第2人到第5人,每位同学都与第1个位置上的同学比高矮,就像打擂台,如果比他高,则交换位置。程序代码如下页图5所示。
● 从算法的迭代优化入手——让程序变得有深度
有一些程序,虽然能够做出来,但是算法并不优化,也不高效,这时候就要引导学生主动思考优化的办法,由简到难,螺旋上升。
以判断素数为例,首先引导学生理解素数的含义,即除了1和它本身之外,没有其他约数的整数,称为素数。如何判断一个数n只有1和它本身之外,没有其他的约数呢?学生首先会想到枚举穷举的方法,即先假设n是一个素数,然后从2开始,到n的前一位之间,每个数拿出来看有没有能把n除尽的数,发现1个多余的约数,说明当初的假设不成立,就不是素数。
如图6所示,即通过开关变量的方法找除1和它本身之外还有没有其它约数的程序,代码如图7所示。
在图7的程序中,输入一个数n,其循环判断一共n-2次,对一个比较小的数影响不大,但是对一个较大的数,其判断的次数是比较多的,如n=100003,要循环判断100001次才能知道它是不是素数,其实我们只要找到一个约数,不管后面还有没有其他约数,都可以通过break结束判断跳出循环,从而减少循环执行的次数,第1次优化版本如图8所示。
图8这段程序对于一个非素数而言可以起到优化作用,但对于一个素数而言,其判断的次数并未减少,仍然需要循环n-2次,才能判断出是不是素数,通过分析得知:发现一个数超过一半后就只剩下它自己一个约数了,所以可以减少枚举的范围,第2次优化版本如图9所示。
经过上面的范围缩小,执行效率优化了一半,只需要5000次,还可以更优化吗?答案是肯定的。笔者发现约数都是成对出现的,如12的约数,有1与12,2与6,3与4三对约数,后面的都又重复了。就是说,12其实只要判断到3点几左右,即只要枚举到n的平方根即可(如图10)。
通过上面的优化方法,这次只需要判断316次左右,这对于一个数可能影响不大,但是穷举判断一个范围内的数是否为素数,其优化效率是显著的。另外,还可以加计数器统计出程序执行的次数和消耗的时间,这样会更直观。当然,学生可能会问还有没有更优化的判断素数的方法,那筛选法求素数可以作为拓展题让学生思考。
总而言之,教师在帮助学生认识程序算法的时候,要多从生活中的情境出发,化难为易,让程序算法变得有温度;从一些趣味游戏出发,感受它的平易近人,保持学生对程序设计的激情和热度;同时也要适时地螺旋上升,不断迭代从而增加它的深度。把握好这“三度”,才能让程序算法入门教学变得更有趣。