created by r@vi mi$hr@

Banner 468

www.pccccorner..tk

lesson 7-Arrays & Vectors

Posted by r@vi mi$hr@ on - -

7. Arrays and Vectors
To be able to use
arrays and vectors to
collect objects
To implement partially
filled arrays
To be able to pass
arrays to methods
To learn about
common array
algorithms
To build classes
containing arrays and
vectors
To learn how to use
two-dimensional
arrays
Arrays
An array is a collection
of data items of the
same type.
Every element of the
collection can be
accessed separately
by using index.
In Java, array indexing
starts from 0.
Array can be
constructed using
double[ ] data = new
double[10];
An Array Reference
and an Array
Using Arrays to Store
Data
To access the fifth
element in an array,
we use
data[4] = 35.5;
System.out.println
(“The price = ” + data
[4]);
sum = sum + data[4];
double[ ] data; // error :
not initialized
data[0] = 10.5; // assign
a value to data[0]
Bounds Error
double[ ] data = new
double[10];
// we can access data
[0], data[1], … data[9]
data[10] = 35.5; //
cause
ArrayIndexOutOfBound
sException
Size of the array:
arrayRefName.length
double[ ] data = new
double[10];
for (int i = 0; i < data.length; i++) if (data[i] < lowest) lowest = data[i]; Don’t combine array access and index increment x = v[i++]; => x = v[i]; i+
+;
Array Initialization
int[] primes = new int
[5];
primes[0] = 2; primes
[1] = 3; primes[2] = 5;
primes[3] = 7; primes
[4] = 11;
// better to use the
following
int[ ] primes = {2, 3, 5,
7, 11};
Copying Arrays
Reference
double[] data = new
double[10];
// … fill array
double[] prices;
prices = data; // copy
reference of array
Make a true copy of
array
double[] prices = new
double[data.length];
for (int j = 0; j < data.length; j++) prices[j] = data[j]; Better if we use the static System.arrayCopy method System.arrayCopy (from, fromStart, to, toStart, count); System.arrayCopy (data, 0, prices, 0, data.length); Partially Filled Arrays When we need to set the size of an array before you know how many elements there are, we can make an array that is large enough and partially fill it. final int DATA_LENGTH = 1000; double[] data = new double[DATA_LENGTH]; then keep a variable that tells how many elements are actually used int dataSize = 0; // for collect size of array and increment this variable every time data is added to the array double price = console.readDouble(); data[dataSize] = price; dataSize++; Remember! Not to access the data over the datasize for (int j=0; j < dataSize; j++) // not data.length System.out.println(data [j]); and not to overfill the array if (dataSize < data.length) // OK { data[dataSize] = price; dataSize++; } else // Array is full { System.out.println (“Sorry, array is full”); } If the array fills up, we can create a new, larger array; copy all elements into the new array; and then attach the new array to the old array variable. if (dataSize >= data.length)
{ //
double[] newData = new
double[2 * data.length];
// copy data
System.arrayCopy(data,
0, newData, 0,
data.length);
//create new reference for
"new data" ่
data = newData;
}
Suppose we want to
write a program that
reads a set of prices
offered by 10 vendors
for a particular product
and then prints them,
marking the lowest
one.
public class BestPrice
{ public static void
main(String[] args)
{ final int DATA_LENGTH =
1000;
double[] data = new
double[DATA_LENGTH];
int dataSize = 0;
// read data
ConsoleReader
console = new
ConsoleReader
(System.in);
boolean done = false;
while (!done)
{ System.out.println
("Enter price, 0 to
quit:");
double price =
console.readDouble();
if (price == 0) // end of
input
done = true;
else if (dataSize < data.length) { // add price to data array data[dataSize] = price; dataSize++; } else // array is full { System.out.println ("Sorry, the array is full."); done = true; } } // compute lowest price if (dataSize == 0) return; // no data double lowest = data [0]; for (int i = 1; i < dataSize; i++) if (data[i] < lowest) lowest = data[i]; // print out prices, marking the lowest one for (int i = 0; i < dataSize; i++) { System.out.print(data [i]); if (data[i] == lowest) System.out.print(" <-- lowest price"); System.out.println(); } } } Array Parameters and Return Values The method to compute the average of an array of floating- point numbers public static double average(double[] data) { if (data.length == 0) return 0; double sum = 0; for (int j = 0; j < data.length; j++) sum = sum + data[j]; return sum / data.length; } double[] prices = { 10.5, 24.5, 30.5, 10.0, 50.4 }; System.out.println (“Price average = ” + average(prices)); Array Parameters When an array is passed to a method, the array parameter contains a copy of the reference to the argument array. A method can modify the entries of any array that you pass to it. The method can return an array if the returning result consists of a collection of values of the same type. A method can return an array public static int[] randomData(int length, int n) { Random generator = new Random(); int[] data = new int [length]; for (int j = 0; j < data.length; j++) data[j] = generator.nextInt(n); return data; } Array Algorithms Finding a Value: want to know the price of first product that has price lower or equal 1000 double [] prices; double targetPrice = 1000; int j = 0; boolean found = false; while (j < prices.length && !found) { if (prices[j] <= targetPrice) found = true; else j++; } if (found) System.out.println(“Item” + j + “ has a price of” + prices[j]); Counting: want to know the number of product that has price lower or equal 1000 double [] prices; double targetPrice = 1000; int count = 0; for (int j = 0; j < prices.length; j++) { if (prices[j] <= targetPrice) count++; } System.out.println(count + “ computers.”); Removing an Element from an Unordered Array If we want to remove an element from an unordered array, we simply overwrite the element to be removed with the last element of the array. However, an array cannot be shrunk to get rid of the last element, so we have to used the technique of a partially filled array. Removing an Element : Array not sorted public class Remove1 { public static void main(String[] args) { ConsoleReader console = new ConsoleReader (System.in); String[] staff = new String[5]; staff[0] = "Harry"; staff [1] = "Romeo"; staff[2] = "Dick"; staff[3] = "Juliet"; staff [4] = "Tom"; int staffSize = staff.length; print(staff, staffSize); System.out.println ("Remove which element? (0 - 4)"); int pos = console.readInt(); // overwrite the removed element with the last element staff[pos] = staff [staffSize - 1]; staffSize--; print(staff, staffSize); } /** Prints an array of strings @param s the string array @param sSize the number of strings in the array */ public static void print (String[] s, int sSize) { for (int i = 0; i < sSize; i++) System.out.println(i + ": " + s[i]); } } Remove an Element from an Ordered Array After removing an element, we have to move all elements beyond the element to be removed by one slot. Removing from an Ordered Array public class Remove2 { public static void main(String[] args) { ... int staffSize = staff.length; print(staff, staffSize); System.out.println ("Remove which element? (0 - 4)"); int pos = console.readInt(); // shift all elements above pos down for (int i = pos; i < staffSize - 1; i++) staff[i] = staff[i + 1]; staffSize--; print(staff, staffSize); } } Inserting an Element Suppose we want to insert an element in the middle of an array, we must move all elements beyond the insertion location by one slot. When we insert an element, we start moving at the end of an array, move that element, then go to the one before it. This operation is in reverse order from removing operation. public class Insert { public static void main(String[] args) { String[] staff = new String[6]; staff[0] = “Mary”; staff[1] = “Ben”; staff[2] = “Sandy”; staff[3] = “Janet”; staff[4] = “Peter”; int staffSize = staff.length - 1; System.out.print ("Insert before which element? (0 - 4) "); int pos = console.readInt(); // shift all element after pos up by one for (int i = staffSize; i >
pos; i--)
staff[i] = staff[i - 1];
// insert new element
into freed slot
staff[pos] = "New,
Nina";
staffSize++;
print(staff, staffSize);
}
Parallel Arrays, Arrays
of Objects
and Array as Object
Data
When we want to
analyze a data set that
contains more than
one data item, such as
a data set that contains
the names, prices, and
quality of a collection
of products.
We want to look for
products that give
good quality at low
price.
The problem with this
program is that it
contains three arrays
of the same length.
Bestdata.java
public class BestData
{ public static void
main(String[] args)
{ final int DATA_MAX =
500;
String[] name = new
String[DATA_MAX];
double[] price = new
double[DATA_MAX];
int[] score = new int
[DATA_MAX];
int Size = 0;
// read data from
console
ConsoleReader
console = new
ConsoleReader
(System.in);
Boolean done = false;
while (!done)
{ System.out.println
(“Enter name or leave
blank when done: ”);
String inLine =
console.readLine();
if (inLine == null ||
inLine.equals(“ ”))
done = true;
else if (Size < DATA_ MAX) { name[Size] = inLine; System.out.println (“Enter price: “); inLine = console.readLine(); price[Size] = Double.parseDouble (inLine); System.out.println (“Enter score: “); inLine = console.readLine(); score[Size] = Integer.parseInt (inLine); Size++; } else { System.out.println (“Sorry, the array is full. “); done = true; } } // compute best buy if (Size == 0) return; // no data double best = score[0] / price[0]; for (int j = 0; j < Size; j+ +) if (score[j] / price[j] >
best)
best = score[j] / price
[j];
final int COLUMN_WIDTH
= 30;
for (int j = 0; j < Size; j+ +) { System.out.print (name[j]); int pad = COLUMN_ WIDTH - name[j].length(); for (int k = 1; k < = pad; k+ +) System.out.print(“ “); System.out.print(“ $” + price[j] +“ score = “ + score[j]); if (score[j] / price[j] == best) System.out.print(“ <-- best buy “); System.out.println(); } } } Parallel Arrays The problem with Bestdata.java is that it contains three parallel arrays namely name[j], price[j], and score[]. We must ensure that the arrays always have the same length and that each slice is filled with values that actually belong together. We can solve this problem by turning this concept into class. Product.java class Product { private String name; private double price; private int score; public Product(String n, double p, int s) { name = n; price = p; score = s; } public String getName () { return name; } public double getPrice () { return price; } public int getScore() { return score; } } Bestproduct.java public class BestProduct { public static void main(String[] args) { final int DATA_MAX = 500; Product[] data = new Product[DATA_MAX]; int Size = 0; // read data from console ConsoleReader console = new ConsoleReader (System.in); Boolean done = false; while (!done) { Product p = readProduct(console); if (p == null) done = true; else if (Size < DATA_ MAX) { data[Size] = p; Size++; } else { System.out.println (“Sorry, the array is full.”); done = true; } } // compute best buy if (Size == 0) return; // no data double best = data[0] .getScore() / data[0] .getPrice(); for (int j = 1; j < Size; j+ +) { double ratio = data[j] .getScore() / data[j] .getPrice(); if (ratio > best)
best = ratio;
}
// print out data
for (int j = 0; j < Size; j+
+)
{ printProduct(data[j]);
if (data[j].getScore() /
data[j].getPrice() ==
best)
System.out.print(“ <--
best buy “);
}
}
public static Product
readProduct
(ConsoleReader in)
{ System.out.println
(“Enter name or leave
blank when done:”);
String name =
in.readLine();
if (name == null ||
name.equals(“ “))
return null;
System.out.println
(“Enter price: “);
String inLine =
in.readLine();
double price =
Double.parseDouble
(inLine);
System.out.println
(“Enter score: “);
inLine = in.readLine();
int score =
Integer.parseInt
(inLine);
return new Product
(name, price, score);
}
public static void
printProduct(Product p)
{ final int WIDTH = 30;
System.out.print
(p.getName());
int pad = WIDTH –
p.getName().length;
for (int j = 1; j <= pad; j+
+)
System.out.print(“ “);
System.out.print(“ $” +
p.getPrice() + “ score =
“ +
p.getScore());
}
}
Example:
PolygonTest.java
Arrays as Object Data
import
java.applet.Applet;
import
java.awt.Graphics;
import
java.awt.Graphics2D;
import
java.awt.geom.Line2D;
import
java.awt.geom,Point2D
;
public class
PolygonTest extends
Applet
{ public void paint
(Graphics g)
{ Graphics2D g2 =
(Grahpics2D) g;
Polygon triangle = new
Polygon(3);
triangle.add(new
Point2D.Double(40, 40)
);
triangle.add(new
Point2D.Double(120,
160));
triangle.add( new
Point2D.Double(20,
120));
double x = 200;
double y = 200;
double r = 50;
Polygon pentagon =
new Polygon(5);
for (int j = 0; j < 5; j++)
pentagon.add(new
Point2D.Double(
x + r * Math.cos(2 *
Math.PI * j / 5),
y + r * Math.sin(2 *
Math.PI * j / 5)));
triangle.draw(g2);
pentagon.draw(g2);
}
}
// Polygon class
definition
class Polygon
{ public polygon(int n)
{ corners = new
Point2D.Double[n];
cornerCount = 0;
}
public void add
(Point2D.Double p)
{ if (cornerCount <
corners.length)
{ corners[cornerCount]
= p;
cornerCount++;
}
}
public void draw
(Graphics2D g2)
{ for (int j = 0; j <
cornerCount; j++)
{ Point2D.Double from
= corners[j];
Point2D.Double to =
corners[(j+1) %
corners.length];
g2.draw(new
Line2D.Double(from, to);
}
}
private Point2D.Double
[] corners;
private int
cornerCount;
}
Example
To generate a triangle,
we can use the
following segment of
code:
Polygon triangle = new
Polygon(3);
triangle.add(new
Point2D.Double(40,40))
;
triangle.add(new
Point2D.Double
(120,160));
triangle.add(new
Point2D.Double(20,120)
);
Another kind of
geometric shape is
called a regular
polygon which has all
sides of the same
length.
A regular n-gon with
center (x,y) and radius
r has n corners, c0, c1,
…, cn-1, where
ci = (x+r•cos(2p i/n), y
+r•sin(2p i/n))
A regular polygon can
be generated by:
Polygon pentagon =
new Polygon(5);
for (int j = 0; j < 5; j++)
pentagon.add(new
Point2D.Double(
x +r*Math.cos
(2*Math.PI*j/5),
y+r*Math.sin
(2*Math.PI*j/5)));
PolygonTest.java
import
java.applet.Applet;
import
java.awt.Graphics;
import
java.awt.Graphics2D;
import
java.awt.geom.Line2D;
import
java.awt.geom.Point2D
;
public class
PolygonTest extends
Applet
{ public void paint
(Graphics g)
{ Graphics2D g2 =
(Graphics2D) g;
Polygon triangle = new
Polygon(3);
triangle.add(new
Point2D.Double(40,40))
;
triangle.add(new
Point2D.Double
(120,160));
triangle.add(new
Point2D.Double(20,120)
);
double x = 200;
double y = 200;
double r = 50;
Polygon pentagon =
new Polygon(5);
for (int j = 0; j < 5; j++)
{ pentagon.add(new
Point2D.Double(
x+r*Math.cos
(2*Math.PI*j/5),
y+r*Math.sin
(2*Math.PI*j/5)));
}
triangle.draw(g2);
pentagon.draw(g2);
}
}
// define polygon class
class Polygon
{ public Polygon(int n)
{ corners = new
Point2D.Double[n];
cornersSize = 0;
}
public void add
(Point2D.Double p)
{ if (cornersSize <
corners.length)
{ corners[cornersSize]
= p;
cornersSize++;
}
}
public void draw
(Graphics2D g2)
{ for (int j = 0; j <
cornersSize; j++)
{ Point2D.Double from
= corners[j];
Point2D.Double to =
corners[(j+1) %
corners.length];
g2.draw(new
Line2D.Double(from,
to));
// Line2D.Double line =
new Line2D.Double
(from, to);
// g2.draw(line);
}
}
private Point2D.Double
[] corners;
private int cornersSize;
}
Vector
A Vector is a container
of objects that grows
automatically
A Vector can hold
objects of any types
Internally, the Vector
class keeps an Object
[] array.
There is no limit to the
number of elements
that we add.
We can add new
elements at the end of
the vector with the
add method.
However, vectors are
objects of a class and
not arrays so we
cannot use the []
operator to access
vector.
Instead, we use the
set method to write an
element, and the get
method to read an
element.
products.set(0, p);
Example
// Consider
BestProduct.java
Vector products = new
Vector();
boolean done = false;
while (!done)
{ Product p =
readProduct();
if (p == null) // last
product read
done = true;
else
products.add(p); // add
the object to the end
of the vector
}
Vector positions start
at 0.
The number of
elements stored in a
vector is obtained by
the size method.
int n = products.size();
To read an element
from a vector, we use
the get method:
products.get(i) is the
ith element in the
vector products.
However, because the
return type of the get
method is the class
Object, we must cast
the return value of the
get method to the
correct type.
Product p = (Product)
products.get(i);
An example of a loop
that traverses the
elements of a vector.
for (int j = 0; j <
products.size(); j++)
{ Product p = (Product)
products.get(j);
do something with p;
}
We can also insert an
object in the middle of
a vector by using v.add
(j,p) to add the object
p at position j, move
all elements by one
position, from position
j to the last element in
the vector, and
increase the size of
the vector by 1.
The call v.remove(j)
removes the element
at position j, moves all
elements after the
removed element
down by one position,
and reduce the size of
the vector of the
vector by 1.
Since numbers are not
objects in Java, we
cannot have vectors
of numbers.
To store sequence of
integers, floating-point
numbers, or boolean
values, we must use
wrapper classes.
The classes Integer,
Double, and Boolean
wrap numbers and
truth values inside
objects.
These wrapper
objects can be stored
inside vectors.
The Double class is a
number wrapper.
There is a constructor
that makes a Double
object out of a double
value:
Double d = new Double
(29.74);
Conversely, the
doubleVal method
retrieves the double
value that is stored
inside the Double
object.
double x =
d.doubleValue();
To add a number into a
vector, we first
construct a wrapper
object, then add the
object to the vector:
Vector data = new
Vector();
data.add(new Double
(29.95));
To retrieve the
number, we need to
cast the return value
of the get method to
Double, then call the
doubleValue method:
double x = ((Double)
data.get(0))
.doubleValue();
Converting Vectors to
Arrays
The advantage of
vectors is the dynamic
growth since we need
not know the final size
of the vector.
The disadvantage is
the cumbersome
access syntax.
We can convert a
vector to an array with
the copyInfo method:
// read values into a
vector
vector productVector =
new Vector();
boolean done = false;
while (!done)
{ Product p =
readProduct();
if (p == null)
done = true;
else
productVector.add(p);
}
// allocate an array of
the correct size
Product[] products =
new Product
[productVector.size()];
// copy the elements
from the vector to the
array
productVector.
copyInfo(products);
for (int j = 0; j <
products.length; j++)
do something with
products[j];
Two-Dimensional
Arrays
An arrangement
consisting of rows and
columns of values is
called a two-
dimensional array or
matrix.
To construct a 2D
array, we need to
specify how many ros
and columns we need,
for example
int[][] powers = new
int[10][8];
To access a particular
element in the matrix,
we specify two
subscripts in separate
brackets:
powers[3][4] =
Math.pow(2, 4);
Two-Dimensional
Arrays
In Java, 2D arrays are
stored as arrays of
arrays:
int[][] powers = new
int[10][8];
For example, power is
an array of 10 objects,
each of which is an int
[] array of length 8.
The number of rows is:
int nrows =
powers.length;
The number of
columns is:
int ncols = power[0]
.length;
// See example:
Table2.java
Table2.java
public class Table2
{ public static void
main(String[] agrs)
{ final int COL_WIDTH =
10;
int[][] powers = new
int[10][8];
for (int i = 0; i <
powers.length; i++)
for (int j = 0; j <
powers[i].length; j++)
powers[i][j] = (int)
Math.pow(i+1, j+1);
printTable(powers,
COL_WIDTH);
}
public static void
printTable(int[][] table,
int width)
{ for (int i = 0; i <
table.length; i++)
{ for (int j = 0; j < table
[i].length; j++)
{ System.out.print
(format(table[i][j],
width));
}
System.out.println();
}
}
public static String
format(int n, int width)
{ String nstr = “” + n;
while (nstr.length() <
width)
nstr = “ “ + nstr;
return nstr;
}
}