第8章 字串與陣列
第8章 字串與陣列 8-1 一維陣列的處理 8-2 二維和多維陣列 8-3 字串處理 8-4 動態陣列、不規則陣列與參數傳遞 8-5 陣列排序與搜尋
8-1 一維陣列的處理 8-1-1 陣列的基礎 8-1-2 宣告一維陣列 8-1-3 For Each迴圈走訪陣列元素與邊界函數 ViLLE – 5.1 陣列的宣告與初值 8-1-3 For Each迴圈走訪陣列元素與邊界函數
8-1-1 陣列的基礎-說明 「陣列」(Arrays)是一種程式語言的基本資料結構,屬於一種循序性的資料結構。日常生活最常見的範例是一排信箱,如下圖所示:
8-1-1 陣列的基礎-VB陣列 Visual Basic語言的陣列屬於參考資料型別,它可以將相同資料型別的變數集合起來,使用一個名稱代表,以索引值存取元素,每一個元素相當於是一個變數,如下圖所示:
8-1-2 宣告一維陣列-語法 Visual Basic陣列同樣使用【Dim】關鍵字來宣告,我們可以在宣告同時指定陣列尺寸。一維陣列的宣告語法,如下所示: Dim 陣列名稱(最大索引) As 資料型別 或 Dim 陣列名稱(0 To 最大索引) As 資料型別 陣列元素個數為括號的最大索引數加一,也可以使用To關鍵字指出範圍。
8-1-2 宣告一維陣列-範例 例如:宣告一維陣列來儲存學生姓名和成績,如下所示: Dim arrNames(4) As String Dim arrGrades(4) As Integer 上述程式碼宣告2個一維陣列,一為整數陣列;一是字串陣列,括號值是陣列最大的索引值。索引值是從0開始,0~4共有5個元素。
8-1-2 宣告一維陣列- 一維陣列的初值 我們也可以在宣告陣列時,不指定陣列最大索引值,而直接指定陣列元素的初值,如下所示: Dim arrGrades() As Integer = {60, 89, 75, 68, 90} 上述程式碼宣告的一維陣列大小就是初值的個數,陣列索引的最大值是初值個數減一。 在Visual Basic 2010版可以直接使用Dim宣告且指定初值,而不用指定資料型別,陣列會自動依初值判斷資料型別,如下所示: Dim arrNames = {"陳會安", "江小魚", "楊過", "小龍女", "張無忌"}
8-1-2 宣告一維陣列- 存取一維陣列的元素值 我們可以使用索引值以指定敘述來指定陣列值,如下所示: arrGrades(0) = 60 arrGrades(1) = 89 arrGrades(2) = 75 arrGrades(3) = 68 arrGrades(4) = 90 上述指定敘述使用索引值來指定陣列元素值。同樣方式可以取出陣列元素值,如下所示: Dim grade As Integer grade = arrGrades(3)
8-1-2 宣告一維陣列- Visual Basic專案 Visual Basic專案:Ch8-1-2 在Windows應用程式建立學生姓名字串陣列和成績的整數陣列,學號是陣列索引值。只需輸入學號的索引值,就可以取得陣列元素的學生姓名和成績,如下圖所示:
ViLLE – 5.1 陣列的宣告與初值 請啟動ViLLE,在【五. 陣列】目錄下,選【1. 陣列的宣告與初值】,按【Run】鈕模擬執行此範例程式,如下圖所示:
8-1-3 For Each迴圈走訪陣列元素與邊界函數-走訪陣列(語法) For Each 變數 In 陣列 程式區塊 Next 上述「變數」可以取得陣列的一個元素,變數需要和陣列屬於相同資料型別,迴圈自動從索引0開始,每執行一次迴圈取得一個元素值並且自動移至下一個元素,直到沒有元素為止。
8-1-3 For Each迴圈走訪陣列元素與邊界函數-走訪陣列(範例) 例如:計算上一節arrGrades陣列元素的成績總和,如下所示: For Each item In arrGrades totalGrade += item Next 上述程式碼的變數item是陣列元素,每執行一次,就將陣列元素值加到totalGrade,最後變數totalGrade就是陣列元素的總和。
8-1-3 For Each迴圈走訪陣列元素與邊界函數-陣列邊界函數 如果使用For/Next迴圈(Do/Loop迴圈也可以)來存取陣列元素,我們可以搭配Visual Basic函數來取得陣列邊界,傳入參數是陣列變數,如下表所示:
8-1-3 For Each迴圈走訪陣列元素與邊界函數-Visual Basic專案 Visual Basic專案:Ch8-1-3 在Windows應用程式可以顯示每位學生的姓名和成績,和全班總分和平均成績,如下圖所示:
8-2 二維和多維陣列-說明 「二維陣列」(Two-dimensional Array)或多維陣列都是一維陣列的擴充。如果將一維陣列想像成一度空間的線,二維陣列就是二度空間的平面,三維陣列即空間。 在日常生活中的二維陣列應用非常廣泛,只要是平面的表格,都可以轉換成二維陣列來表示。例如:月曆、功課表和成績單等。在Visual Basic宣告學生成績的二維陣列也是使用Dim,如下所示: Dim arrGrades(,) As Integer = { { 54, 68, 93 }, { 67, 78 , 89} }
8-2 二維和多維陣列-圖例 二維陣列擁有2個索引,左索引(Left Index)指出元素位在哪一列,右索引(Right Index)指出位在哪一欄,使用2個索引值就可以存取指定的二維陣列元素。
8-2 二維和多維陣列-VB2010陣列初值 Visual Basic 2010版可以直接使用Dim宣告二維陣列且指定初值,而不用指定資料型別,它會自動依初值判斷維度和資料型別,如下所示: Dim arrGrades = { { 54, 68, 93 }, { 67, 78 , 89} }
8-2 二維和多維陣列-指定元素值 二維陣列如果沒有指定陣列初值,我們需要在宣告時指定陣列尺寸,如下所示: Dim arrGrades(1, 2) As Integer arrGrades(0,0)=54 arrGrades(0,1)=68 arrGrades(0,2)=93 arrGrades(1,0)=67 arrGrades(1,1)=78 arrGrades(1,2)=89
8-2 二維和多維陣列-走訪元素 在設定陣列值後,存取二維陣列需要使用二層巢狀迴圈,如下所示: For i = 0 To 1 For j = 0 To 2 totalGrades(i) += arrGrades(i, j) Next j Next i
8-2 二維和多維陣列- Visual Basic專案 Visual Basic專案:Ch8-2 在Windows應用程式輸入學生各科成績後,可以計算學生的總分和平均分數,如下圖所示:
8-3 字串處理 8-3-1 字串的基礎 8-3-2 字串長度與大小寫轉換 8-3-3 取出子字串與字串反轉 8-3-4 子字串的搜尋與取代
8-3-1 字串的基礎-說明 Visual Basic字串是String資料型別的變數或字串字面值,字串是0或多個依序的Char資料型別的字元,以雙引號括起的文字內容,如下所示: Dim str As String = "Visual Basic程式設計範例教本" Dim str1 As String str1 = "ASP.NET網頁製作徹底研究"
8-3-1 字串的基礎-新字串值 不過Visual Basic字串內容並不能更改,也就是說,一旦建立字串後,就無法改變其值,只能重新指定成新的字串值或另一個字串變數,如下圖所示:
8-3-2 字串長度與大小寫轉換-說明 Visual Basic函數可以取得字串長度、進行英文字母大小寫轉換和刪除頭尾的空白字元,如下表所示:
8-3-2 字串長度與大小寫轉換- Visual Basic專案 Visual Basic專案:Ch8-3-2 在Windows應用程式可以測試上表的字串函數,取得字串長度、轉換成小寫和刪除空白字元,讀者可以自行執行程式來測試函數的執行,如下圖所示:
8-3-3 取出子字串與字串反轉-說明 Visual Basic提供Mid()、Left()和Right()等函數,可以從字串中取出所需的子字串,或是反轉字串,如下所示:
8-3-3 取出子字串與字串反轉- Visual Basic專案 Visual Basic專案:Ch8-3-3 在Windows應用程式可以測試上表的字串函數,取出所需的子字串,讀者可以自行執行程式來測試函數的執行,如下圖所示:
8-3-4 子字串的搜尋與取代-說明 對於多行文字方塊輸入的一整篇文章來說,我們可以使用Visual Basic函數來搜尋與取代字串。Visual Basic字串搜尋與取代函數的說明,如下表所示: 函數 說明 InStr(start, stmt, find[, type]) 在參數stmt字串的start位置(從1開始)開始找尋find字串,如果找到,傳回找到的位置,沒有找到傳回0 Replace(stmt, find, replacement[ , start, count, type] ) 在參數stmt字串找尋find字串,將它取代成replacement字串,start是開始找尋位置(預設從1開始),count是取代次數(預設值-1表示取代所有找到的字串)
8-3-4 子字串的搜尋與取代- Visual Basic專案 Visual Basic專案:Ch8-3-4 在Windows應用程式建立類似文書編輯工具的搜尋和取代功能,如下圖所示:
8-4 動態陣列、不規則陣列與參數傳遞 8-4-1 動態陣列 8-4-2 不規則陣列 8-4-3 傳遞字串與陣列參數 ViLLE – 5.3 傳遞陣列參數
將原來arrGrades陣列大小從5改為7個元素 8-4-1 動態陣列-宣告 Visual Basic陣列可以使用【ReDim】關鍵字在程式執行時,重新調整尺寸。不過ReDim不能宣告陣列,只能更改已經宣告的陣列尺寸,如下所示: Dim arrGrades(4) As Integer ……… ReDim arrGrades(6) 將原來arrGrades陣列大小從5改為7個元素
8-4-1 動態陣列-保留陣列內容 如果陣列已經擁有內容,請使用Preserve關鍵字來保留原陣列的內容,如下所示: ReDim Preserve arrGrades(6) 上述程式碼可以放大陣列尺寸,當然放大陣列尺寸並不會有問題,如果縮小陣列的話,陣列裁剪部分的資料還是會遺失。
8-4-1 動態陣列-二維動態陣列 對於是二維以上的多維陣列,我們可以變更指定維度的尺寸,如果使用Preserve關鍵字,就只能變更最後1個維度的尺寸,如下所示: Dim arrTable(10, 20) ………. ReDim Preserve arrTable(10, 30)
8-4-1 動態陣列- Visual Basic專案 Visual Basic專案:Ch8-4-1 在Windows應用程式測試Visual Basic動態陣列,首先建立尺寸5的一維陣列儲存學生成績,因為這學期轉入2位轉學生,所以放大尺寸為7,並且計算調整前後的學生平均成績,如下圖所示:
8-4-2 不規則陣列-說明 Visual Basic語言的不規則陣列(Jagged Array)是讓陣列元素可以是另一個陣列,換句話說,二維陣列的第1維元素值是另一個一維陣列,而且可以是不同尺寸的一維陣列。
8-4-2 不規則陣列-宣告 在Visual Basic程式碼宣告不規則陣列的語法和之前的二維陣列有一些不同,我們是宣告Array物件。例如:因為每一班的學生人數並不同,所以準備宣告儲存3個班級學生姓名的不規則陣列,如下所示: Dim arrClasses(2) As Array Dim arrStudents1 = {"陳會安", "江小魚"} Dim arrStudents2 = {"張無忌", "楊過", "小龍女"} Dim arrStudents3 = {"陳允傑", "陳允東"} 然後指定不規則陣列的元素值為這三個陣列,如下所示: arrClasses(0) = arrStudents1 arrClasses(1) = arrStudents2 arrClasses(2) = arrStudents3
8-4-2 不規則陣列-不規則陣列的初值 在宣告不規則陣列的同時也可以指定陣列初值,不過,不同於二維陣列的初值,在元素外需要額外括號"( )"括起,如下所示: Dim arrClasses()() = { ({"陳會安", "江小魚"}), ({"張無忌", "楊過", "小龍女"}), ({"陳允傑", "陳允東"})}
8-4-2 不規則陣列-使用巢狀迴圈走訪不規則陣列 在建立二維不規則陣列後,我們可以使用二層For Each巢狀迴圈走訪二維不規則陣列,如下所示: For Each arr In arrClasses For Each item In arr out &= item & vbTab Next out & = vbNewLine
8-4-2 不規則陣列-Visual Basic專案 Visual Basic專案:Ch8-4-2 在Windows應用程式建立二維不規則陣列儲存三個班的學生姓名資料,因為每一班的學生數不同,然後顯示每一班的學生清單,如下圖所示:
8-4-3 傳遞字串與陣列參數-說明 程序與函數的參數如果是字串或陣列,因為字串與陣列都是參考資料型別,此時ByVal和ByRef參數傳遞的差異,如下表所示:
8-4-3 傳遞字串與陣列參數-範例 例如:在程序與函數中,使用指定敘述將參數指定成其他陣列,如下所示: Sub ReplaceArray(ByVal A() As Integer) Dim B() As Integer = {10, 20, 30} A = B …………. End Sub 上述程序將參數的陣列A指定成新陣列B,事實上,並不會影響原參數陣列A,因為傳值方式不能指定成新陣列。
8-4-3 傳遞字串與陣列參數-Visual Basic專案 Visual Basic專案:Ch8-4-3 在Windows應用程式建立最大值和取代字串程序,可以取得陣列最大值和取代字串,程序參數是使用ByVal傳遞陣列;字串是使用ByRef方式呼叫,如下圖所示:
ViLLE – 5.3 傳遞陣列參數 請啟動ViLLE,在【五. 陣列】目錄下,選【3. 傳遞陣列參數】,按【Run】鈕模擬執行此範例程式,如下圖所示:
8-5 陣列排序與搜尋 8-5-1 陣列的排序 8-5-2 陣列的搜尋
8-5-1 陣列的排序-基礎 排序工作是將一些資料依照特定原則排列成遞增或遞減的順序。例如:整數陣列Data的內容,如下所示: Data(0)=89 Data(1)=34 Data(2)=78 Data(3)=45 上述陣列以整數值的大小,將陣列內容依遞增的順序來排序。其排序結果如下所示: Data(0)=34 Data(1)=45 Data(2)=78 Data(3)=89 上述陣列Data已經完成排序,其大小順序如下所示: Data(0) < Data(1) < Data(2) < Data(3)
8-5-1 陣列的排序-泡沫排序法(說明) 泡沫排序法(Bubble Sort)是使用交換方式來進行排序,可以將較小元素逐漸移動至陣列開始,較大元素慢慢浮向陣列的最後,如同水缸中的泡沫,慢慢往上浮,故稱為泡沫排序法。
8-5-1 陣列的排序-泡沫排序法(過程) 泡沫排序法的過程是使用交換方法,在陣列中找尋最大值,例如:原始陣列內容,如下所示: Data(0)=89 Data(1)=34 Data(2)=78 Data(3)=45 陣列依序比較陣列元素0和1,元素1和2,元素2和3來交換陣列元素,如下所示: Data(0)=89 > Data(1)=34 => Data(0)=34 Data(1)=89 交換 Data(1)=89 > Data(2)=78 => Data(1)=78 Data(2)=89 交換 Data(2)=89 > Data(3)=45 => Data(2)=45 Data(3)=89 交換 陣列最大值89一步步往陣列尾端移動。接著重複上述步驟,每次縮小1個元素後,再重新比較陣列元素,就可以完成陣列元素的排序。
8-5-1 陣列的排序-泡沫排序法(函數) Sub Bubble(ByVal Data() As Integer) Dim i, j, length, temp As Integer length = UBound(Data) For i = length To 0 Step -1 For j = 0 To length - 1 If Data(j + 1) < Data(j) Then temp = Data(j + 1) ' 交換 Data(j + 1) = Data(j) Data(j) = temp End If Next j Next i End Sub
8-5-1 陣列的排序- Visual Basic專案 Visual Basic專案:Ch8-5-1 在Windows應用程式輸入4個數字,按下按鈕,就可以將4個數字從小到大進行排序,如下圖所示:
8-5-2 陣列的搜尋-基礎 搜尋是在資料中找出是否存在與鍵值相同的資料,如果資料存在,就進行後續的資料處理。例如:查尋電話簿是為了找朋友的電話號碼,然後與他連絡。在書局找書也是為了找到後買回家閱讀。 搜尋方法依照搜尋的資料分為兩種,如下所示: 沒有排序的資料:針對沒有排序的資料執行搜尋,我們需要從資料的第1個元素開始比較,從頭到尾以確認資料是否存在。 已經排序的資料:因為資料已經排序,所以搜尋就不需從頭開始一一比較。例如:在電話簿找電話,相信沒有人是從電話簿的第1頁開始找,而是直接從姓名出現的頁數開始找,因為電話簿已經依照姓名進行排序。
8-5-2 陣列的搜尋-線性搜尋法 線性搜尋法(Sequential Search)是從陣列的第1個元素開始走訪整個陣列,然後一個一個比較是否擁有搜尋的鍵值,因為需要走訪整個陣列,所以陣列資料是否排序都無所謂。 換句話說,在Visual Basic程式可以使用迴圈來走訪陣列,以便比較陣列是否有指定的鍵值。
8-5-2 陣列的搜尋-線性搜尋法 (程式碼) target = CInt(txtSearch.Text) For i = 0 To UBound(Data) If target = Data(i) Then lblOutput.Text = "找到鍵值在位置: " & i isFound = True Exit For End If Next i
8-5-2 陣列的搜尋-二元搜尋法 二元搜尋法(Binary Search)是一種分割資料的搜尋方法,搜尋資料是已經排序的資料。二元搜尋法先檢查排序資料的中間元素,如果等於鍵值就是找到;如果小於鍵值,表示資料在前半段;否則在後半段。然後繼續分割半段資料來重覆上述操作,直到找到或已經沒有資料可以分割為止。 例如:Data陣列索引的上下範圍分別是low和high,中間元素mid是(low + high)\2。在執行二元搜尋時分成三種情況,如下所示: 搜尋鍵值小於陣列的中間元素:鍵值在資料陣列的前半部。 搜尋鍵值大於陣列的中間元素:鍵值在資料陣列的後半部。 搜尋鍵值等於陣列的中間元素:找到搜尋的鍵值。
8-5-2 陣列的搜尋-二元搜尋法(程式碼) target = CInt(txtSearch.Text) low = 0 high = UBound(Data) Do mid = (low + high) \ 2 If Data(mid) = target Then lblOutput.Text = "找到鍵值在位置: " & mid isFound = True Exit Do ElseIf Data(mid) > target Then high = mid - 1 ' 前半段 Else low = mid + 1 ' 後半段 End If Loop Until low > high
8-5-2 陣列的搜尋- Visual Basic專案 Visual Basic專案:Ch8-5-2 在Windows應用程式建立線性和二元搜尋,可以在陣列執行搜尋,因為二元搜尋需要已排序資料,所以提供上一節泡沫排序法來排序陣列資料,如下圖所示:
End