郝啟強


摘要:在新課程背景下,程序算法作為程序設計的靈魂,在培養學生計算思維能力方面的地位和作用越來越突出,可是在程序算法入門教學中,很多學生甚至包括教師都對涉及的程序算法望而卻步,因為不好講,也不太好理解,所以大多停留在編程語言語法和編程工具的介紹上。本文作者結合多年程序設計教學經驗,嘗試在新課程背景下對初中程序設計算法入門做一些探索,為學生打開程序設計的大門。
關鍵詞:程序設計;計算思維;算法
中圖分類號: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次左右,這對于一個數可能影響不大,但是窮舉判斷一個范圍內的數是否為素數,其優化效率是顯著的。另外,還可以加計數器統計出程序執行的次數和消耗的時間,這樣會更直觀。當然,學生可能會問還有沒有更優化的判斷素數的方法,那篩選法求素數可以作為拓展題讓學生思考。
總而言之,教師在幫助學生認識程序算法的時候,要多從生活中的情境出發,化難為易,讓程序算法變得有溫度;從一些趣味游戲出發,感受它的平易近人,保持學生對程序設計的激情和熱度;同時也要適時地螺旋上升,不斷迭代從而增加它的深度。把握好這“三度”,才能讓程序算法入門教學變得更有趣。