《算法與程序設(shè)計(jì)》是《信息技術(shù)》(選修1)的內(nèi)容,同學(xué)們通過(guò)該課程的學(xué)習(xí),不僅掌握了許多編程技巧,而且用計(jì)算機(jī)分析問(wèn)題和解決問(wèn)題的能力也得到了提高。但我們?cè)诮虒W(xué)實(shí)踐中發(fā)現(xiàn),對(duì)于許多初學(xué)者,迅速掌握循環(huán)結(jié)構(gòu)并用于具體問(wèn)題的解決,并不是一件容易的事情。下面我們結(jié)合一些具體實(shí)例,分析循環(huán)結(jié)構(gòu)的特點(diǎn)及其編程方法。
一、 循環(huán)從FOR語(yǔ)句開始
循環(huán)結(jié)構(gòu)可以減少程序重復(fù)書寫的工作量,用于描述重復(fù)執(zhí)行某段算法的問(wèn)題,這是程序設(shè)計(jì)中最能發(fā)揮計(jì)算機(jī)特長(zhǎng)的程序結(jié)構(gòu)。應(yīng)用循環(huán)結(jié)構(gòu)進(jìn)行程序設(shè)計(jì),關(guān)鍵是正確地構(gòu)造出循環(huán)體,以及設(shè)置好循環(huán)變量的初值、循環(huán)的終止條件。FOR語(yǔ)句是一種最簡(jiǎn)單、基礎(chǔ)的循環(huán)結(jié)構(gòu),它的初值、終值和步長(zhǎng)顯式地體現(xiàn)在語(yǔ)句中。因此,我們可以從FOR語(yǔ)句出發(fā),逐步探究其它循環(huán)結(jié)構(gòu)的特點(diǎn)及用法,以期達(dá)到事半功倍的效果。
例1 求1+1/2+1/3+……+1/100的值。
Private Sub Command1_Click()
s = 0
For i = 1 To 100
s = s + 1 / i
Next i
Print \"s=\"; s
End Sub
這是一個(gè)簡(jiǎn)單的循環(huán)程序,程序中包含了循環(huán)結(jié)構(gòu)的一些基本概念,如循環(huán)變量、初值、終值、步長(zhǎng)、循環(huán)體和累加和等,教學(xué)時(shí)可對(duì)其進(jìn)行適當(dāng)?shù)淖冃?、改造或擴(kuò)充,如修改變量的初值,改累加為累乘,或在循環(huán)體中強(qiáng)行修改循環(huán)變量的值等,讓學(xué)生對(duì)這些基本概念有一個(gè)初步的了解。
例2 計(jì)算S=1+-+-……+-的值。
Private Sub Command1_Click()
s = 1
k = 1
For i = 1 To 100
s = s + 1 / (i * (i + 1)) * k
k = -k
Next i
Print \"s=\"; s
End Sub
這是上例的延伸和擴(kuò)展,編程時(shí)要解決三個(gè)問(wèn)題:①第一項(xiàng)與其它項(xiàng)有不同的規(guī)律,如何處理?②從第二項(xiàng)開始,每項(xiàng)的分母均由兩個(gè)相鄰的自然數(shù)相乘,如何表示?③如何實(shí)現(xiàn)運(yùn)算符號(hào)的交替變換?若能引導(dǎo)同學(xué)們找出解決這些問(wèn)題的方法,對(duì)循環(huán)結(jié)構(gòu)的理解也就前進(jìn)一大步了。
例3 輸入10個(gè)實(shí)數(shù),輸出其中的最大數(shù)和最小數(shù)。
Private Sub Command1_Click()
x = InputBox(\"請(qǐng)輸入第1個(gè)數(shù)\")
Max = x
Min = x
For i = 2 To 10
x = InputBox(\"請(qǐng)輸入第2到第10個(gè)數(shù)\")
If x > Max Then Max = x
If x < Min Then Min = x
Next i
Print \"max=\"; Max, \"min=\"; Min
End Sub
在例1、例2中,循環(huán)變量的值直接參與了算式的運(yùn)算。但在本例中,循環(huán)的作用只是用于統(tǒng)計(jì)輸入的個(gè)數(shù),循環(huán)變量的不同作用有助于學(xué)生更好地理解循環(huán)結(jié)構(gòu)。此外,我們?cè)诮虒W(xué)中引入了算法設(shè)計(jì)及預(yù)處理的概念,讓學(xué)生了解要想寫出一個(gè)好程序就必須先設(shè)計(jì)出一個(gè)好算法,就養(yǎng)成一個(gè)好的編程習(xí)慣。
二、 循環(huán)從DO語(yǔ)句深入
FOR循環(huán)可以解決許多重復(fù)執(zhí)行的問(wèn)題,但FOR循環(huán)一般用于解決初值和終值已知,且步長(zhǎng)值為順序遞增或遞減的問(wèn)題。對(duì)于滿足某種條件的重復(fù)執(zhí)行問(wèn)題,建議在熟練掌握FOR循環(huán)后,引入DO循環(huán)加予解決。
例4 已知=1++×+××+×××+……,當(dāng)序列中某乘積項(xiàng)的值小于0.000000001時(shí),表達(dá)式的值可作為的近似值,試計(jì)算的近似值。
Private Sub Command1_Click()
s = 0
k = 1
i = 1
Do While k >= 0.000000001
s = s + k
k = k * i / (2 * i + 1)
i = i + 1
Loop
s = 2 * s
Print \"pi=\"; s
End Sub
這道題看起來(lái)很復(fù)雜。其實(shí),通過(guò)分析我們可以發(fā)現(xiàn),序列中的每一項(xiàng)均是在前一項(xiàng)的基礎(chǔ)上再累乘上一個(gè)新的分?jǐn)?shù),因此我們可以用一個(gè)變量存放累加和,用另一個(gè)變量存放累乘積,從而構(gòu)造出滿足要求的循環(huán)結(jié)構(gòu)。因無(wú)法確定重復(fù)執(zhí)行的次數(shù),本題最好采用DO循環(huán)來(lái)實(shí)現(xiàn)。在應(yīng)用DO循環(huán)時(shí),要注意提醒學(xué)生設(shè)置好循環(huán)變量的初值,在循環(huán)體內(nèi)要有能夠改變循環(huán)控制條件的語(yǔ)句,否則將陷入死循環(huán)。
例5 利用輾轉(zhuǎn)相除法求兩個(gè)正整數(shù)的最大公約數(shù)。
Private Sub Command1_Click()
m = InputBox(\"請(qǐng)輸入第1個(gè)數(shù)\")
n = InputBox(\"請(qǐng)輸入第2個(gè)數(shù)\")
If m < n Then t = m: m = n: n = t
r = m Mod n
Do While r <> 0
m = n
n = r
r = m Mod n
Loop
Print \"最大公約數(shù)為:\"; n
End Sub
在前面幾個(gè)例子中,循環(huán)變量一般是有規(guī)律地遞增或遞減,循環(huán)特征明顯,代碼相對(duì)簡(jiǎn)單。本題應(yīng)用了一個(gè)經(jīng)典的算法輾轉(zhuǎn)相除法,求解的問(wèn)題要經(jīng)過(guò)提煉和設(shè)計(jì)才能運(yùn)用循環(huán)結(jié)構(gòu)。編程時(shí)應(yīng)用了條件分支,輾轉(zhuǎn)相除以及變量替換等概念和方法,循環(huán)的終止條件是動(dòng)態(tài)生成的,學(xué)生不易理解與掌握,教學(xué)時(shí)可先手工模擬再編程實(shí)現(xiàn)。
DO循環(huán)有四種不同的格式,區(qū)別在于循環(huán)終止條件的判別方式及執(zhí)行順序上,只要熟練掌握了其中的一種格式,其它格式的應(yīng)用也就水到渠成了。
三、 循環(huán)從多重嵌套中提升
多重嵌套的循環(huán)結(jié)構(gòu)是一個(gè)比較難的知識(shí)點(diǎn),也是容易使學(xué)生喪失信心的內(nèi)容。教學(xué)時(shí)不要急于求成,可從最簡(jiǎn)單的二重嵌套循環(huán)出發(fā),先讓學(xué)生手工模擬程序的執(zhí)行過(guò)程,了解循環(huán)變量的變化情況,再逐步深入解決實(shí)際問(wèn)題。
例6 輸出一張“九九乘法表”。
程序一:
Private Sub Command1_Click()
For i = 1 To 9
For j = 1 To 9
Print Tab((j - 1) * 13); i; \"*\"; j; \"=\"; i * j;
Next j
Next i
End Sub
程序二:
Private Sub Command1_Click()
For i = 1 To 9
For j = 1 To i
Print Tab((j - 1) * 13); i; \"*\"; j; \"=\"; i * j;
Next j
Next i
End Sub
程序三:
Private Sub Command1_Click()
For i = 1 To 9
For j = 1 To i
Print Tab((j - 1) * 13); j; \"*\"; i; \"=\"; i * j;
Next j
Next i
End Sub
“九九乘法表”是一個(gè)不錯(cuò)的二重循環(huán)入門例,“程序一”許多學(xué)生可以很快寫出。接著,可引導(dǎo)學(xué)生觀察“程序二”,了解如何通過(guò)改變循環(huán)變量的初值或終值來(lái)改變循環(huán)執(zhí)行的次數(shù),從而改變“九九乘法表”的形狀,最后再與“程序三”比較,找出它們之間的異同點(diǎn),更好地理解多重嵌套循環(huán)的執(zhí)行過(guò)程。
例7 輸出自然數(shù)1~100之間的所有素?cái)?shù)。
Private Sub Command1_Click()
Print 2; \" \"
For i = 3 To 100
flag = True
For j = 2 To Int(Sqr(i))
If i Mod j = 0 Then
flag = False
Exit For
End If
Next j
If flag = True Then Print i; \" \"
Next i
End Sub
這道題運(yùn)用了三種編程技巧:①將與其它素?cái)?shù)性質(zhì)不同的素?cái)?shù)2單獨(dú)輸出,簡(jiǎn)化編寫步驟;②設(shè)置了一個(gè)布爾類型的標(biāo)志變量,用于判斷找到的數(shù)是否為素?cái)?shù);③利用exit for語(yǔ)句中止內(nèi)層循環(huán)的執(zhí)行,提高運(yùn)行速度。編程時(shí)可讓學(xué)生先寫出判斷一個(gè)數(shù)是否為素?cái)?shù)的程序段(內(nèi)循環(huán)),然后在它的外面再嵌套另一重循環(huán),輸出題目要求的其它素?cái)?shù)。
例8 將2~100中的所有自然數(shù)分解為其質(zhì)因子的乘積,輸出如下形式:
2=2
3=3
4=22
……
100=2255
Private Sub Command1_Click()
For i = 2 To 100
k = i
j = 2
First = True
Print k; \"=\";
Do While k > 1
Do While k Mod j = 0
If First = True Then
Print j;
First = False
Else
Print \"*\"; j;
End If
k = k j
Loop
j = j + 1
Loop
Next i
End Sub
這是一道比較難的多重循環(huán)嵌套練習(xí)題。其中,最外面的FOR循環(huán)用于提供所有待分解的自然數(shù),中間的DO循環(huán)用于分解出每個(gè)數(shù)中不同的因子,最里面的DO循環(huán)用于分解出每個(gè)數(shù)中相同的因子,環(huán)環(huán)相扣,層層遞進(jìn),綜合應(yīng)用了本文中介紹的多種編程技巧,同學(xué)們?nèi)裟茏屑?xì)揣摩認(rèn)真分析,一定會(huì)有許多感觸和收獲。
總之,在教學(xué)中按照FOR、Do...Loop多重嵌套的順序授課較好。For語(yǔ)句中對(duì)于循環(huán)結(jié)構(gòu)的基本要素都提煉出來(lái)了,后者需要挖掘隱含的語(yǔ)法要素;如后變量及初值,循環(huán)體中要有修改循環(huán)變量值的表達(dá)式使得循環(huán)結(jié)束。由于一開始的新課例子導(dǎo)入激發(fā)了學(xué)生的求知欲,渲染了良好的課堂氣氛,讓學(xué)生帶著問(wèn)題聽課,有的放矢,從而提高了教學(xué)效果。