陳維龍

摘要:VB是常用的程序設計語言,簡捷、易用,運行穩定,運行效率較高。在數學教學中,常遇到一些邏輯復雜,個例較多,難于歸納總結的問題,教師在準備與講析這些問題的時候很難找到解決思路,無所適從。筆者將這些問題通過VB編譯成程序來運行處理,可以充分發揮計算機的優勢,迅速解決這些數學難題。
關鍵詞:VB;窮舉法;數學問題
● 問題提出
前幾天,上小學四年級的兒子指著試卷上的一個填空題,問我怎么做,題目描述:“用4、5、6、7、8這五個數組成一個兩位數和一個三位數,乘積最大是( ? ),乘積最小是( ? )”。初一看好像是很簡單的一道題,我和妻子兩個人想當然地找出了多個組合,可馬上都被自己的新發現打破,百思不得其解。于是,又上網搜索相關問題,得出各類答案與解決方案,但都有一些缺陷,有些規則看似有用,但當把題中的五個數字更換為其他數時,規則又不一定適用。其間,我們雖然已找到了最大值和最小值,但卻不知道是不是恰當的答案。于是,我想到設計一個程序,用程序來解決這個問題,并試圖在此基礎上找到解答此類問題的規則。
● 算法分析
此類問題,在找不出明顯的規則之前,只有通過窮舉法羅列出符合要求的全部組合,計算出每個組合的最大值與最小值,將每個組合的組合規則記錄到規則數組中,當窮舉完所有的組合后,整理規則數組,去除重復的值,也就是組合規則,然后可以找出最大值組合與最小值組合的規律。因為此類題很少出現0這個數,所以我設計時只用了1~9這九個數,總結出來的規律可適用于有0出現求最大乘積的情況,求最小乘積的情況要稍作變通。描述算法如下:
①本程序通過嵌套循環,從1~9這九個數中選取隨機五個不重復的數,作為題干中要求的五個個位數,并列出所有可能出現的組成一個兩位數和一個三位數的組合。
②在①循環中,每次找到符合要求的五個個位數后,將其分別填入五個文本框中,并均作如下運算,先采用冒泡法,對這五個數進行從小到大排序,并依次填回五個文本框中。然后對用于存放乘數、乘積及數值組合規則的四個數組進行重定義,以便能夠存儲新得到的六個數及兩個數值組合規則。然后對剛取得的五個個位數進行操作,通過嵌套循環,分別將任意兩個或三個組成一個數,再將剩下的三個數或兩個數組成另一個數,連同所得到的兩個乘積及數值組合規則一起存入數組。當這五個個位數的所有可能組合均運算成功并存入相應數組后,從乘積數組中找出最大值和最小值,以及與之相對應的兩組乘數和數值組合規則,輸出到富文本框RB1,同時將數值組合規則寫入最大值規則與最小值規則數組str_gzb()中。
③判斷①循環是否符合循環要求,如果符合,再進入下一次循環。如果已完成所有符合要求的組合的運算,則退出循環。
④去除規則數組str_gzb()中重復項,統計出最大值和最小值的組合規則。也可以將得要的結果拷貝到Excel中,手工統計組合規則。
⑤數值組合規則規定如下:五個數字中最小的數所處的位置用A表示,最大的數所處的位置用E表示,其他類推。如題干中的4、5、6、7、8五個數,組成一個兩位數47,其取值規則就是AD,組成一個三位數568,其取值規則就是BCE,在取值規則數組中記錄為“ADBCE”。
● VB程序設計過程
在有了比較完善的算法分析之后,我利用VB程序進行了設計。過程為:
①在VB中建立一個工程,增加一個窗體form1。
②在窗體中添加數組控件text1(0~4)、command1、Richtextbox1等控件,并設置command1控件的Caption屬性為“開始計算!”,設置Richtextbox1控件的名稱為“RB1”,調整各控件到適當位置。
③添加窗體load代碼,聲明所要用到的各個動態數組,在command1中添加運算過程代碼,添加用于記錄所選取數值組合規則的過程GL的代碼。
④運算測試,修繕程序。
⑤將工程輸出為可執行文件。
● 源碼
利用VB程序設計完成后,所有的源代碼也一一完成,清晰地展現了利用此程序進行數學運用、算法分析的過程。部分源代碼如下。
Private Sub Form_Load()
Dim S() As Integer ? ? ?'存放乘積
Dim G(), H() As Integer ?'存放乘數一 ,乘數二
Dim Str_Gz() As String ?'存放當前算術表述式規則
Dim str_gzb() As String ? '存放所有數據組合中最大值和最小值規則數組
Dim Str_bs As String ? ?'保存當前算術表述式的變量
Dim Str_Gz1, Str_Gz2 As String ?'存放本次循環最大值和最小值的數值組合規則
End Sub
Private Sub Command1_Click()
Dim Ta, Tb, Tc, Td, Te As Integer ?'存放五個隨機的個位數的變量
Dim nIndex As Long ? ? ? '循環變量
Dim A, B, C, D, E, F As Integer ? ?'循環變量
ReDim str_gzb(2)
RB1.Text = RB1.Text & "所選數字 Max算式 Max規則 Max乘積Min算式 Min規則 Min乘積" & vbCrLf ? ?'設置列表的簡易列頭
For Ta = 1 To 9
For Tb = 1 To 9
For Tc = 1 To 9
For Td = 1 To 9
For Te = 1 To 9
If Ta <> Tb And Ta <> Tc And Ta <> Td And Ta <> Te And Tb <> Tc And Tb <> Td And Tb <> Te And Tc <> Td And Tc <> Te And Td <> Te Then
Text1(0).Text = Ta
Text1(1).Text = Tb
Text1(2).Text = Tc
Text1(3).Text = Td
Text1(4).Text = Te
……
ReDim Preserve str_gzb(UBound(str_gzb()) + 2) ?'不作判斷直接重定義這個數組,會增加一些空值,但不影響對數值組合規則的統計
str_gzb(UBound(str_gzb()) - 1) = Str_Gz1
str_gzb(UBound(str_gzb())) = Str_Gz2
……
RB1.Text = RB1.Text & "******************************************" & vbCrLf
RB1.Text = RB1.Text & "乘積最大的組合規則和乘積最小的組合規則:" & vbCrLf
For i = 0 To UBound(str_gzb) ?'此循環部分代碼借鑒網絡代碼,去除最值組合規則數組中重復項
For j = 0 To i – 1
If str_gzb(i) = str_gzb(j) Then Exit For
Next
If j = i Then RB1.Text = RB1.Text & str_gzb(i) & vbCrLf
Next
End Sub
……
Else
If N(i) = A Then GL = GL & "A" "A"表示此位置是五個數中最小的數,其余類推
If N(i) = B Then GL = GL & "B"
If N(i) = C Then GL = GL & "C"
If N(i) = D Then GL = GL & "D"
If N(i) = E Then GL = GL & "E"
End If
Next i
End Function
● 運行測試
設計完此程序后,我進行了測試,因為運算量大,程序運行時間一般需要一個小時以上,程序也可能出現假死現象,只要耐心等待即可。運行結果如下圖(圖片根據運行結果進行了拼接)。
由分析結果可以看出,此類問題的組合規則如下:將最大數作為兩位數的十位,第四大數作為兩位數的個位,將第二大數作為三位數的百位,第三大數作為三位數的十位,最小數作為三位數的個位,這樣組合出來的兩位數和三位數乘積最大;將最小數作為兩位數的十位,第三大數作為兩位數的個位,將第四大數作為三位數的百位,第二大數作為三位數的十位,最大數作為三位數的個位,這樣組合出來的兩位數和三位數乘積最小。
● 思考
作為一款經典的高級程序設計語言,VB的生命力依然旺盛,依然可以作為中小型程序的首選語言。