CSCI 201
Introduction to Algorithm Design home | homework index | labs index |
SPRING 2007 |
In this lab, we will work with arrays.
An array is a data structure. It is an ordered collection of objects or primitive data elements. You access a specific element of an array by stating the collection name followed by the specific element's index number in that collection.
In Java, arrays are objects. To create an
array you create an object. The syntax for creating an array object
is slightly different from that used for other objects. To create an
array of 5 int
's called
tom
, you would type:
int[] tom = new int[5];
On the left-hand side of the assignment
operator, int[]
is the data type
array of int
and tom
is
the name of the array object. On the
right-hand side of the assignment operator, the operator
new
is being used to create an array object
containing a collection of five integer
variables.
Each element in the array has an index number associated with it. The index number of the first element is 0. Each element after that is numbered sequentially, up to the last element. This means that the index number of the last element of the array is one less than the size of the array. You can almost think of each element in an array as a variable. Because you access the "variables" of an array via an index number, there are some pretty powerful tricks you can do with arrays.
If you wanted to set 5 int
variables equal to 0, how would you do it? Perhaps like this:
june = 0; tom = 0; may = 0; scarlet = 0; apple = 0;
This is a tedious way of doing things, and you run the risk of making a mistake. To do the same task using an array, you could do the following:
int[] stuff = new int[5]; for (int i = 0; i < 5; i ++) { stuff[i] = 0; }
This is a much more efficient way of doing things. Notice that each
time the loop variable is incremented, a different element of the
array is set equal to zero. Using a for
-loop in this manner,
you can
easily perform a complex task on all of the (or specific) elements of an
array. The following Stack N' Heap demonstrates how to create and
initialize an array of integers storing the numbers from
one to five. For
simplicity, we will show the elements of the array as existing on the
stack; but, because they are contained in an object, they
are actually stored on the heap.
Code
int[] myArray = new int[5];
for (int i = 0; i < myArray.length; i ++) { myArray[i] = i + 1; } |
Stack
|
Heap
|
Temporary
|
As you see, loops and arrays are often used together. By using a loop variable as an index into an array, you can perform tasks on a large number of variables which just a few lines of code.
Download Array.zip, a ZIP file containing a NetBeans project named
Array and unZIP this project
into your csci/201 directory.
Try to make your Projects panel look
something like the following picture before continuing.
Compile and run the Array
project.
Now take a look at the class MyOpClass1
of the array
package.
package array ; // Adds all elements of the array and returns the total class MyOpClass1 implements SpecArrayOp { public int testFunc(int[] V) { for(int i = 0; i < V.length; i++) tot += V[i]; } return 0 ; }
As you see, MyOpClass1
consists of just one
method, testFunc
, and that
testFunc
has a single parameter,
V
, of type int[]
.
testFunc
's purpose is to return an integer
value. It returns the sum of all elements of the array that it
receives as input.
In this case, you want to add up the elements of the array.
You do this by initializing a variable that will
hold a running total of the array elements to zero.
Then within the loop, you add each element of
the array into that running total.
Finally, you want to return the total. Your completed code
for MyOpClass1
should look something like
that show below.
package array ; // Adds all elements of the array and returns the total class MyOpClass1 implements edu.unca.cs.csci201.labaids.SpecArrayOp { public int testFunc(int[] V) { int Sum = 0 ; for(int i = 0; i<V.length; i++) { Sum = Sum + V[i] ; } return Sum ; }
You will also be writing code to modify arrays.
Take a look at the class MyModClass1
of the array
package.
package array ; // Add one to each element of the array class MyModClass1 implements edu.unca.cs.csci201.labaids.SpecArrayMod { public void testFunc(int[] V) { for(int i=0;i<V.length;i++) { } } }
MyModClass1
also consists of just one
method testFunc
that
receives a single parameter. However, this
time testFunc
doesn't return anything.
Its purpose is to modify values of the element of array
V
.
In this part of the lab, you will need to put some
interesting code into the loop body. We'll get you
started by showing you a completed solution for
MyModClass1
.
package array ; // Add one to each element of the array class MyModClass1 implements edu.unca.cs.csci201.labaids.SpecArrayMod { public void testFunc(int[] V) { for(int i=0;i<V.length;i++) { V[i] = V[i]+1 ; } } }
As you might expect, most of your modifications will not be
that easy. In several cases, you will also need to change
the initialization and termination code of the for
loop.
You are to modify the main
method of
Array
so that it tests twelve different classes.
These twelve classes have a testFunc
method which
implements the twelve array operations shown below.
Most of these tasks are fairly simple. If you are
writing a lot of code, you may have wandered off the path.
Before showing you the table, we're going to give you some hopefully helpful hints for a couple of the more difficult cases.
Suppose you wanted to average the five numbers 18, 19, 20, 22, and 24 to the nearest integer. If you add all the numbers together you get 103. The average of the five as a real number is 20.6, so if you rounded that you'd get 21.
How to you round to an integer in Java?
You know that 103/5
is 20.
It's also the case that the rather ugly
(int) ((double)103/5)
is also 20.
You have three choices here. One is to add 0.5 to the double
result before converting it into an integer, as in
(int) ((double)103/5 + 0.5)
.
The second is to add one-half of the number of
elements to the sum before doing the division, as in
(103 + 5/2)/5
.
The third is to use Math.round
, as in
Math.round((float)103/5)
.
When you have a spare moment, think about why the last case used
(float)
rather than (double)
.
MyModClass5
is really not that hard.
(Especially if you're a CSCI 201 lab instructor who has
seen hundreds of solutions in the last few years.)
Take a look at the following diagram
0 1 2 3 4 5 | | | | | | +-------------------+ swap 0 and 5 +-----------+ swap 1 and 4 +---+ swap 2 and 3
Now look at the operations:
Can you see a pattern in the numbers? How are the numbers related to the size
of the array, which was 6 in this case.
Since the i'th element from the beginning of the
array is V[i]
, what is the i'th element from
the end of the array?
Why do you need exactly 3 swaps? How
does this relate to the array size?
What happens if the array size is even, what if it is odd?
Let's say that α
and β
are variables (or array locations such as V[i]
),
and we want to swap them. If we write
α = β ;
β = α ;
it won't work, because the initial value of α
will be lost.
We must use a temporary variable to store
the initial value of α
before we overwrite
α
.
Now you can play a little game of musical chairs with the variables.
Move α
to the temporary,
move β
to α
,
and finally move the temporary (which contains the
original α
)
to β
as in
int t = α ;
α = β ;
β = t ;
MyOpClass6
is also doable.
Here are the actions required to set each element,
except the first and last, to the average
of its two surrounding neighbors.
7 2 5 8 1 4 | | | | | | +-------+ 2 will be substituted with (7 + 5)/2 = 6 +-------+ 5 will be substituted with (2 + 8)/2 = 5 +-------+ 8 will be substituted with (5 + 1)/2 = 3 +-------+ 1 will be substituted with (8 + 4)/2 = 6 7 6 5 3 6 4
Now look at the operations:
Do not forget that we have to substitute 5 with average of the original
elements (2+8)/2 not with (6+8)/2. Can you see a pattern in these numbers? If
current element is V[i]
. What
is the name of the left neighbor? What is the name of the right neighbor?
You can use the clone
method, as in V.clone()
to make a new copy of an array.
In some cases, it would be useful to use the testFunc
method on one class in another. You can do this, but it isn't
easy. You have to say something like
(new MyOpClass2()).testFunc(V)
which is simply hideous. It might be easier to just use
cut-and-paste.
Array Operations | ||
---|---|---|
Class Name |
testFunc Return Value |
|
MyOpClass1 |
Adds all elements of the array and returns the total | |
MyOpClass2 |
Returns the largest element of the array | |
MyOpClass3 |
Returns the smallest element of the array | |
MyOpClass4 |
Adds all the even elements of the array and returns the total | |
MyOpClass5 |
Returns an integer average of all elements in the array | |
MyOpClass6 |
Adds the smallest and largest elements of the array and returns their sum | |
Array Modification | ||
Class Name |
Operation performed in testFunc |
|
MyModClass1 |
Add one to each element of the array. | |
MyModClass2 |
Multiply each element by three. | |
MyModClass3 |
Set all array elements to zero. | |
MyModClass4 |
Set the i'th array element to i. | |
MyModClass5 |
Reverse the array. | |
MyModClass6 |
Relax the array, that is, set each element to the average of its two surrounding neighbors, except for the first and last elements which are left unchanged. |
Last modified: 03/01/07