Two dimensional arrays. A two dim array is doubly subscripted… It has rows and columns Tables of...

Preview:

Citation preview

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• 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)

Row by row traversal

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

Display of functionality

The UPS rates application using comboboxes

Contents of weight combobox

Contents of zone combobox

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"}

Same,but using textboxes

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

A Rainfall simulator

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 buttonPrivate 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 buttonPrivate 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

An exam recorder

Recording grades

Add grades for students

Compute averages for each student

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.

Generic array manipulation

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

Sum by row

Sum a column

Recommended