410 likes | 427 Views
Two dimensional arrays. Two dimensional arrays. A two dim array is doubly subscripted… It has rows and columns Tables of data are examples of two-dim arrays. As with one-dim arrays, row and column length is fixed once the array is allocated
E N D
Two dimensional arrays • A two dim array is doubly subscripted… • It has rows and columns • Tables of data are examples of two-dim arrays. • As with one-dim arrays, row and column length is fixed once the array is allocated • Arrays are homogeneous, so an array can’t store (for example) both floats and Strings
Applications in this ppt • UPS lookup using comboboxes • UPS lookup using textboxes • Yearly Rainfall simulator • Roster/exam grades • Processing rows (or columns) of a 2-d array
Manipulating 2-d arrays • For a one dimensional array we usually use 1 loop to traverse contents. • For 2-D array we’ll usually use 2 loops, a “row” loop and a “column” loop. • The “outer” loop is the slow loop and determines the order of the traversal. • Each row (or column) or a 2-d array is a 1-D array
Declaring data • If the data is known in advance it can be declared and initialized as a field value Dim data(,) As Integer = {{12, 34, 56, 75}, {9, 2, 100, 6}, {500, 400, 300, 200}}
To display the data (row by row) in a listbox: For row = 0 To 2 strdata = "" For col = 0 To 3 strdata = strdata & data(row, col) & ControlChars.Tab Next Listdata.Items.Add(strdata) Next
exercises • For the previous example, write code for summing all the contents of the array. • For the previous example, write code for finding the largest (smallest) element in the array. • What code would access the “diagonal” elements of a square array? • What code would “transpose” the contents of a square array? (swap rows to columns)
We might be interested in row (or column) computations – say sum contents of a row Dim row, col, sum As Integer sum = 0 'one loop needed to traverse a one dimensional subarray row = Integer.Parse(txtrow.text) For col = 0 To 3 sum = sum + data(row, col) Next
Global (field) array declarations – note doubly subscripted array Dim rates(,) As Decimal = {{1D, 1.5D, 1.65D, 1.85D}, _ {1.58D, 2D, 2.4D, 3.05D}, _ {1.71D, 2.52D, 3.1D, 4D}, _ {2.04D, 3.12D, 4D, 5.01D}, _ {2.52D, 3.75D, 5.1D, 7.25D}} Dim weight() As Integer = {1, 3, 5, 10} Dim zone() As String = {"A", "B", "C", "D"}
The button code Dim weightindex, zoneindex As Integer Dim wtin As Integer wtin = Integer.Parse(txtwt.Text) Dim wtfound, zonefound As Boolean wtfound = False zonefound = False weightindex = 0 zoneindex = 0 While (Not wtfound) And weightindex <= 3 If wtin <= weight(weightindex) Then wtfound = True Else weightindex += 1 End If End While If wtfound = False Then weightindex = 4 End If While zonefound = False And zoneindex <= 3 If Me.txtzone.Text.ToUpper() = zone(zoneindex) Then zonefound = True Else zoneindex += 1 End If End While If zoneindex <= 3 Then ' txtdisplay.Text = weightindex & " " & zoneindex txtdisplay.Text = rates(weightindex, zoneindex).ToString("N") Else MessageBox.Show("weight or zone incorrect", "data error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation) End If
remarks • This is not very realistic, as I did not use real rainfall data to fill my rainfall array. • Real data could easily be incorporated: get (historic) max and min rainfall for each day, and use these numbers in your random generator. • But it shows how a simulator could be built to model weather (or something else). For example, a temperature simulator could be built similarly.
Global (field) values Dim rain(12, 31) As Double Dim nummonths As Integer = 12 Dim months As String() = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"} Dim days As Integer() = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
Form load fills rainfall array randomly Private Sub RainFall_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Dim r As New Random(DateTime.Now.Millisecond) Dim i, j As Integer For i = 0 To nummonths - 1 For j = 0 To days(i) - 1 rain(i, j) = r.NextDouble() * r.Next(0, 5) ’ not a very realistic simulation Next Next End Sub
The day-of-max-rain button Private Sub btnmaxday_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnmaxday.Click Dim i, j, m, d As Integer m = 0 d = 0 For i = 0 To nummonths - 1 For j = 0 To days(i) - 1 If rain(i, j) > rain(m, d) Then m = i d = j End If Next Next ListBox1.Items.Add("Day of max rain was " & months(m) & d & "amt=" & rain(m, d).ToString("N2")) End Sub
The month-of-min-rain button Private Sub btnminmon_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnminmon.Click Dim i, j, m, d As Integer Dim sum, tot As Double tot = 99999 For i = 0 To nummonths - 1 sum = 0 For j = 0 To days(i) - 1 sum += rain(i, j) Next If sum < tot Then m = i tot = sum End If Next ListBox1.Items.Add("Month of min rain was " & months(m) & " amt= " & tot.ToString("N2")) End Sub
Other buttons and functionality • I didn’t code the other buttons. • You could add a button: Redo simulation to refill the rain array again randomly
Fields (globals) used Const classsize = 4 Public students As String() = {"Bob", "Marcy", "Jane", "Pete"} Dim exams(classsize, 3) As Integer
Add a grade button code • use selectedindex from the two comboboxes to see which student/ which exam score is being entered. • Check to make sure a legal row/col was selected and insert the grade into position (row=student#,col=exam#) of the exams array.
Add a grade button code Private Sub btnadd_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnadd.Click Dim row, col As Integer col = cboexam.SelectedIndex() row = cbostudent.SelectedIndex() If row >= 0 And row < 4 And col >= 0 And col < 3 Then exams(row, col) = Integer.Parse(txtexam.Text) Else MessageBox.Show("row=" & row & " col=" & col, "error", MessageBoxButtons.OK) End If txtexam.Text = "" End Sub
Display button • Clear listbox. • Show names and which grades have been recorded. • Exams are all initialized to -99. In the loop, if a legal grade has not been recorded, a message is displayed for this exam. • 2 loops needed to traverse a 2-D array, only one loop is needed for a 1-D array. The outer loop adds a name from the name list onto the string to display, the inner loop adds an exam for this student, each time it goes around.
Display button code Private Sub btndisplay_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btndisplay.Click Dim i, j As Integer Dim displaystring As String ListBox1.Items.Clear() For i = 0 To classsize - 1 displaystring = students(i) For j = 0 To 2 If exams(i, j) = -99 Then displaystring = displaystring & ControlChars.Tab & "no grade" Else displaystring = displaystring & ControlChars.Tab & exams(i, j) End If Next ListBox1.Items.Add(displaystring) Next End Sub
Calculate averages • Clear listbox. • You need a sum (and, optionally, an ave variable) of type double • For each set of scores (for each student) set sum=0. • Add across the row (inner loop) to the sum. • Display the name and average in the listbox.
Additions and improvements • Add labels for checkboxes • Add a clear-all button • Have number of exams be a constant like number of students in this example. • Provide (buttons or combobox for) other exam statistics, like high grade, low grade, and overall mean.
About this example • An array is declared as a field value and filled (either at compile or in form load) • Buttons provided to add across any given row or column • Array declaration at the top of class: Dim data(,) As Integer = {{12, 34, 56, 75}, {9, 2, 100, 6}, {500, 400, 300, 200}}
About this example: formload displays array contents in listbox Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Dim row, col As Integer Dim strdata As String For row = 0 To 2 strdata = "" For col = 0 To 3 strdata = strdata & data(row, col) & ControlChars.Tab Next Listdata.Items.Add(strdata) Next End Sub
Sum by row button Private Sub btnrow_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnrow.Click Dim row, col, sum As Integer sum = 0 'one loop needed to traverse a one dimensional subarray row = Integer.Parse(txtrow.text) For col = 0 To 3 sum = sum + data(row, col) Next ‘outside loop list results Listdata.Items.Add("sum of row " & row & "=" & sum) End Sub