Download ch13 - ComSciGate

Document related concepts

Java ConcurrentMap wikipedia , lookup

Array data structure wikipedia , lookup

Transcript
Chapter 13: Data Structures
Chapter 13
Data Structures
Java Programming
FROM THE BEGINNING
1
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
13.1 Multidimensional Arrays
• Multidimensional arrays have more than one
dimension.
• Java allows arrays to have any number of
dimensions.
• In practice, arrays rarely have more than two
dimensions.
Java Programming
FROM THE BEGINNING
2
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Creating and Initializing a
Multidimensional Array
• The declaration of a multidimensional array will
contain more than one set of square brackets:
int[][] a;
• It’s legal to put some or all of the brackets after
the array name:
int[] a[];
int a[][];
Java Programming
FROM THE BEGINNING
3
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Creating and Initializing a
Multidimensional Array
• The new keyword is used to allocate space for a
multidimensional array:
a = new int[5][10];
a will have 5 rows and 10 columns.
• The declaration of a multidimensional array can
be combined with the allocation of space for the
array:
int[][] a = new int[5][10];
Java Programming
FROM THE BEGINNING
4
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Creating and Initializing a
Multidimensional Array
• The array a can visualized as a table with 5 rows
and 10 columns:
Java Programming
FROM THE BEGINNING
5
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Creating and Initializing a
Multidimensional Array
• Rules for assigning default values to array elements:
– Numbers are set to zero.
– boolean elements are set to false.
– Elements of a reference type are set to null.
• The array a will be full of zeros initially:
Java Programming
FROM THE BEGINNING
6
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Creating and Initializing a
Multidimensional Array
• If an array declaration contains an initializer, it’s not
necessary to use new to allocate space for the array.
• The initializer for a two-dimensional array looks like a
series of one-dimensional array initializers:
int[][] square =
{{8, 3, 4}, {1, 5, 9}, {6, 7, 2}};
• The square array:
Java Programming
FROM THE BEGINNING
7
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Subscripting a Multidimensional Array
• Selecting an element of a multidimensional array
requires more than one subscript.
• If a is a two-dimensional array, the element in row
i, column j can be accessed by writing
a[i][j]
• Each subscript can be a literal, a variable, or any
expression that produces an int value.
• Java requires square brackets around each
subscript: writing a[i, j] would be illegal.
Java Programming
FROM THE BEGINNING
8
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Processing the Elements in a
Multidimensional Array
• The elements of a multidimensional array can be
accessed sequentially or in no particular order.
• For a two-dimensional array, sequential access is
normally done by visiting all elements in row 0,
then all elements in row 1, and so on.
• It’s also possible to visit elements column by
column.
Java Programming
FROM THE BEGINNING
9
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Processing the Elements in a
Multidimensional Array
• Statements that sum the elements in an array a by
visiting the elements row by row:
int sum = 0;
for (int row = 0; row < 3; row++)
for (int col = 0; col < 3; col++)
sum += a[row][col];
• Because the loops are nested, the row and col
variables will take on all possible combinations of
values.
Java Programming
FROM THE BEGINNING
10
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Processing the Elements in a
Multidimensional Array
• Order in which the elements of a will be visited:
a[0][0]
a[0][1]
a[0][2]
a[1][0]
a[1][1]
a[1][2]
a[2][0]
a[2][1]
a[2][2]
• Nested for loops are ideal for processing
multidimensional arrays.
Java Programming
FROM THE BEGINNING
11
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
How Multidimensional Arrays Are Stored
• In Java, a two-dimensional array is a one-dimensional
array whose elements are one-dimensional arrays.
• Let a be the following array:
int[][] a = new int[5][10];
• How a is stored:
Java Programming
FROM THE BEGINNING
12
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
How Multidimensional Arrays Are Stored
• Because a is really a one-dimensional array, it’s
legal to write a.length to find the number of
rows in a.
• The expression a[0].length gives the number
of columns. (The choice of 0 is arbitrary.)
• The length of the next dimension—if a had more
than two dimensions—would be
a[0][0].length, and so on.
Java Programming
FROM THE BEGINNING
13
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
How Multidimensional Arrays Are Stored
• An improved version of the code that uses nested
loops to sum the elements of a two-dimensional
array:
for (int row = 0; row < a.length; row++)
for (int col = 0; col < a[0].length; col++)
sum += a[row][col];
• The literals representing the number of rows and
columns have been replaced by a.length and
a[0].length.
Java Programming
FROM THE BEGINNING
14
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Using Two-Dimensional Arrays as Matrices
• Multidimensional arrays play an important role in
mathematical calculations, because a matrix can
be stored in a two-dimensional array.
• Two example matrices:
Java Programming
FROM THE BEGINNING
15
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Using Two-Dimensional Arrays as Matrices
• A and B can be represented by two-dimensional
arrays:
double[][] a = new double[2][3];
double[][] b = new double[3][2];
• The subscripts will be off by 1, however, as they
were for vectors.
• For example, element aij of the matrix A will be
stored in element a[i-1][j-1] of the array a.
Java Programming
FROM THE BEGINNING
16
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Using Two-Dimensional Arrays as Matrices
• Common operations on matrices include addition,
subtraction, and multiplication.
• Formula for computing the product of A and B:
• In general, A and B can be multiplied only if the
number of columns in A matches the number of
rows in B.
Java Programming
FROM THE BEGINNING
17
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Using Two-Dimensional Arrays as Matrices
• Statements that multiply arrays named a and b,
storing the result in a new array named c:
double[][] c = new double[a.length][b[0].length];
for (int row = 0; row < a.length; row++)
for (int col = 0; col < b[0].length; col++) {
c[row][col] = 0.0;
for (int i = 0; i < b.length; i++)
c[row][col] += a[row][i] * b[i][col];
}
The number of columns in a must be equal to the
number of rows in b.
Java Programming
FROM THE BEGINNING
18
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Using Two-Dimensional
Arrays to Store Images
• Two-dimensional arrays are often used to store
images.
• Images are sometimes stored in gray scale, rather
than in color.
• In a gray-scale image, each pixel is a shade of
gray.
• Typically there are 256 shades, represented by
integers between 0 (black) and 255 (white).
Java Programming
FROM THE BEGINNING
19
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Using Two-Dimensional
Arrays to Store Images
• A sample gray-scale image:
Java Programming
FROM THE BEGINNING
20
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Using Two-Dimensional
Arrays to Store Images
• A two-dimensional array of integers that represents this image:
Java Programming
FROM THE BEGINNING
21
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Using Two-Dimensional
Arrays to Store Images
• Ways to store a full-color image:
– Three parallel two-dimensional arrays (storing the red,
green, and blue components of the pixels)
– A two-dimensional array of Color objects
– A three-dimensional array
Java Programming
FROM THE BEGINNING
22
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Using Two-Dimensional
Arrays to Store Images
• A three-dimensional array that could be used to
store a full-color image:
int[][][] colorImage =
new int[numRows][numColumns][3];
• The pixel at position (row, column) would be
represented by three array elements:
colorImage[row][column][0] — red component
colorImage[row][column][1] — green component
colorImage[row][column][2] — blue component
Java Programming
FROM THE BEGINNING
23
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Using Two-Dimensional
Arrays to Store Images
• Arrays often occupy large amounts of memory,
especially when they have more than one
dimension.
• If numRows and numColumns are both 1000,
the colorImage array will require 12,000,000
bytes of memory (1000  1000  3  4).
• Arrays this large may exceed the limits of a Java
interpreter.
Java Programming
FROM THE BEGINNING
24
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Using Two-Dimensional
Arrays to Store Images
• Memory can often be conserved by switching to a
smaller element type (short instead of int or
float instead of double).
• Switching from int to short will reduce the
colorImage array’s memory requirements by a
factor of 2.
Java Programming
FROM THE BEGINNING
25
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Using Two-Dimensional
Arrays to Store Images
• Storing colors as byte values is possible, even
though byte values range from –128 to 127
instead of 0 to 255.
• By subtracting 128 from each color value when
storing it into the array, color values can be scaled
so that they become legal byte values.
• Switching to byte will reduce the size of the
colorImage array by a factor of 4.
Java Programming
FROM THE BEGINNING
26
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Ragged Arrays
• Each row of a two-dimensional array is an array in its
own right, so there’s no reason that the rows can’t
have different lengths.
• If they do, the array is said to be ragged.
• A table containing distances between major American
cities:
Java Programming
FROM THE BEGINNING
27
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Ragged Arrays
• The table could be stored as a two-dimensional
array with eight rows and eight columns, using a
total of 64 elements.
• However, it’s possible to save space by using a
ragged array instead.
– The elements on the diagonal aren’t used, so there’s no
need to store them.
– The values above the diagonal are symmetric to the
values below the diagonal, so it’s not necessary to store
both groups.
Java Programming
FROM THE BEGINNING
28
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Ragged Arrays
• If a ragged array is initialized at the time the array is
declared, the rows in the initializer can have different
lengths.
• A declaration that creates and initializes an array
containing the distances between cities:
int[][] distances =
{null,
{1110},
{ 710, 1000},
{ 790, 1830, 1090},
{2190, 3020, 2050, 1540},
{ 850, 210,
810, 1610, 2790},
{2480, 3130, 2170, 1910, 390, 2930},
{ 620, 450,
710, 1370, 2650, 240, 2840}};
Java Programming
FROM THE BEGINNING
29
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Ragged Arrays
• There’s no need to store the first row of the table.
• However, the array will be easier to work with if it
has eight rows, corresponding to the eight cities.
• Putting null at the beginning of the array
indicates that row 0 has no elements.
Java Programming
FROM THE BEGINNING
30
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Ragged Arrays
• The appearance of the distances array:
Java Programming
FROM THE BEGINNING
31
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Ragged Arrays
• Creating a ragged array without initializing it is a
little more difficult.
• Steps needed to allocate space for the
distances array without initializing it:
– Create a one-dimensional array with eight elements,
which will be arrays of integers.
– Use a loop to allocate storage for each of the “inner”
arrays.
Java Programming
FROM THE BEGINNING
32
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Ragged Arrays
• Statements that perform both steps:
int[][] distances = new int[8][];
for (int i = 1; i < distances.length; i++)
distances[i] = new int[i];
• The value of distances[0] will be null by
default.
• The length of a row can be changed during program
execution.
• Each row is a separate one-dimensional array, so it can
be replaced by another one-dimensional array of a
different length.
Java Programming
FROM THE BEGINNING
33
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Using Multidimensional Arrays as
Parameters and Results
• Multidimensional arrays can be passed to methods and
returned by methods.
• A method that returns the sum of all the elements in the twodimensional array a:
public static int sumElements(int[][] a) {
int total = 0;
for (int row = 0; row < a.length; row++)
for (int col = 0; col < a[row].length; col++)
total += a[row][col];
return total;
}
• Using a[row].length as the limit on the inner loop
allows the array to have rows of different lengths.
Java Programming
FROM THE BEGINNING
34
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Using Multidimensional Arrays as
Parameters and Results
• Methods that return multidimensional arrays are not
uncommon in Java.
• A method that returns an identity matrix of a specified
rank:
public static double[][] createIdentityMatrix(int rank) {
double[][] matrix = new double[rank][rank];
for (int row = 0; row < rank; row++)
for (int col = 0; col < rank; col++)
if (row == col)
matrix[row][col] = 1.0;
return matrix;
}
Java Programming
FROM THE BEGINNING
35
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Using Multidimensional Arrays as
Parameters and Results
• To save time, createIdentityMatrix
assigns values only to elements on the main
diagonal of matrix.
• Other elements will have the value 0.0 by default.
• A sample call:
double[][] identityMatrix = createIdentityMatrix(3);
Java Programming
FROM THE BEGINNING
36
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Program: Finding the Distance
Between Two Cities
• The FindDistance program will display the distance
between two cities:
This program finds the distance between two cities.
Supported cities: Atlanta, Boston, Chicago, Houston,
Los Angeles, New York, San Francisco, Washington.
Enter starting city: San Francisco
Enter destination city: Atlanta
The distance from San Francisco to Atlanta is 2480 miles.
• The user will be asked to re-enter the name of a city if it doesn’t
match any of the names supported by the program.
• A normal two-dimensional array will be used to store the
distances between cities. A ragged array could be used instead.
Java Programming
FROM THE BEGINNING
37
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
FindDistance.java
// Finds the distance between two major American cities
import jpb.*;
public class FindDistance {
private static final String[] CITY_NAMES =
{"Atlanta", "Boston", "Chicago", "Houston",
"Los Angeles", "New York", "San Francisco",
"Washington"};
private static final int[][] DISTANCES =
{{
0, 1110, 710, 790, 2190, 850, 2480, 620},
{1110,
0, 1000, 1830, 3020, 210, 3130, 450},
{ 710, 1000,
0, 1090, 2050, 810, 2170, 710},
{ 790, 1830, 1090,
0, 1540, 1610, 1910, 1370},
{2190, 3020, 2050, 1540,
0, 2790, 390, 2650},
{ 850, 210, 810, 1610, 2790,
0, 2930, 240},
{2480, 3130, 2170, 1910, 390, 2930,
0, 2840},
{ 620, 450, 710, 1370, 2650, 240, 2840,
0}};
Java Programming
FROM THE BEGINNING
38
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
public static void main(String[] args) {
// Display initial message, including a list of legal
// cities
System.out.println(
"This program finds the distance between two cities.\n"
+ "Supported cities: Atlanta, Boston, Chicago, Houston,\n"
+ "Los Angeles, New York, San Francisco, Washington.\n");
// Call getCityCode to obtain codes for starting city
// and destination city
int start = getCityCode("Enter starting city: ");
int destination = getCityCode("Enter destination city: ");
// Display distance between chosen cities
System.out.println(
"\nThe distance from " + CITY_NAMES[start] + " to " +
CITY_NAMES[destination] + " is " +
DISTANCES[start][destination] + " miles.");
}
Java Programming
FROM THE BEGINNING
39
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
// Prompts user to enter city name; returns corresponding
// city code. If city name is not recognized, allows user
// to enter another name.
private static int getCityCode(String prompt) {
while (true) {
SimpleIO.prompt(prompt);
String cityName = SimpleIO.readLine().trim();
for (int i = 0; i < CITY_NAMES.length; i++)
if (cityName.equalsIgnoreCase(CITY_NAMES[i]))
return i;
System.out.println("City name was not recognized.");
}
}
}
Java Programming
FROM THE BEGINNING
40
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
13.2 The Vector Class
• An array has a fixed number of elements.
• The only way to enlarge an array is to allocate
space for a new, larger array and then copy the
values of the old array into the new one.
• Vectors (instances of the Vector class) resemble
arrays, except that they can grow (or perhaps
shrink) during the execution of a program.
• The Vector class belongs to the java.util
package.
Java Programming
FROM THE BEGINNING
41
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Properties of Vectors
• A vector stores references to objects.
• There’s no limit on the number of objects that can
be stored in a vector, nor is there any restriction on
what type of objects can be stored.
• The elements of a vector, like the elements of an
array, are indexed from 0.
• Key differences between vectors and arrays:
– Vectors can grow or shrink as needed.
– Vectors must contain objects.
Java Programming
FROM THE BEGINNING
42
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Properties of Vectors
• Each vector has a capacity and a capacity
increment.
• The capacity is the number of elements the vector
can store without requiring additional memory.
• When a vector becomes full, Java automatically
increases its capacity by the amount of the
capacity increment.
• The size of a vector—the number of items that it
currently stores—is always less than or equal to its
capacity.
Java Programming
FROM THE BEGINNING
43
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Properties of Vectors
• A vector with a capacity of five and a size of
three:
Two elements of the vector are currently not in
use.
Java Programming
FROM THE BEGINNING
44
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Creating a Vector
• The Vector class has three constructors.
• One of them allows the initial capacity of the vector to
be specified:
Vector v = new Vector(5);
• The capacity of v is five and its size is zero:
Java Programming
FROM THE BEGINNING
45
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Storing Data into a Vector
• The Vector class provides methods that add an
object to a vector in one of three ways:
– Add the object after all objects currently stored in the
vector (addElement).
– Insert the object somewhere in the middle of the vector
(insertElementAt).
– Replace an existing object with the new one
(setElementAt).
• All three methods have a parameter of type
Object, representing the object to be stored.
Java Programming
FROM THE BEGINNING
46
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Storing Data into a Vector
• Examples of calling addElement:
v.addElement("a");
v.addElement("b");
v.addElement("c");
Java Programming
FROM THE BEGINNING
47
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Storing Data into a Vector
• A call of insertElementAt:
v.insertElementAt("d", 1);
• insertElementAt throws an
ArrayIndexOutOfBoundsException if the second
argument isn’t between 0 and the vector’s size.
Java Programming
FROM THE BEGINNING
48
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Storing Data into a Vector
• A call of setElementAt:
v.setElementAt("e", 2);
• ArrayIndexOutOfBoundsException is thrown if
the second argument to setElementAt is out of range.
Java Programming
FROM THE BEGINNING
49
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Storing Data into a Vector
• In a call of insertElementAt, the index at
which the new element is to be inserted must be
less than or equal to the vector’s current size.
• In a call of setElementAt, the index at which
the new element is to be stored must be less than
the vector’s current size.
Java Programming
FROM THE BEGINNING
50
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Retrieving Data from a Vector
• Retrieving objects from a vector is harder than
storing them, because the retrieval methods have
Object as their return type.
• To store an element retrieved from a vector, an
Object variable would have to be used.
• Unfortunately, an Object variable can only be
used to call methods that belong to the Object
class.
• The solution to this problem is to cast the value
returned by the retrieval methods.
Java Programming
FROM THE BEGINNING
51
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Retrieving Data from a Vector
• The elementAt method returns the element
stored at a particular position in a vector.
• If a vector contains only strings, the return value
of elementAt can be cast to String:
String str = (String) v.elementAt(2);
• If the element isn’t a String object, a
ClassCastException will be thrown.
• The firstElement method returns the first
element in a vector:
String str = (String) v.firstElement();
Java Programming
FROM THE BEGINNING
52
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Retrieving Data from a Vector
• The lastElement method returns the last
element in a vector:
String str = (String) v.lastElement();
• The elementAt method throws
ArrayIndexOutOfBounds if its argument is
out of bounds (less than 0 or not less than the
vector’s current size).
• firstElement and lastElement throw
ArrayIndexOutOfBounds if the vector is
empty.
Java Programming
FROM THE BEGINNING
53
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Removing Data from a Vector
• The Vector class also has several methods that
remove elements from a vector.
• The removeAllElements method removes all
elements from a vector:
v.removeAllElements();
Java Programming
FROM THE BEGINNING
54
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Removing Data from a Vector
• The removeElement method removes a single
occurrence of a particular element:
v.removeElement("a");
• If the specified element occurs more than once in
the vector, only the first occurrence is removed.
• removeElement returns a boolean value
(true if a matching element was found and
removed, false otherwise).
Java Programming
FROM THE BEGINNING
55
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Removing Data from a Vector
• The removeElementAt method removes the
element stored at a particular index in the vector:
v.removeElementAt(1);
• When an element is removed from a vector at
position i, both removeElement and
removeElementAt will fill the resulting “hole”
by shifting the elements starting at position i + 1 to
the next lower position.
Java Programming
FROM THE BEGINNING
56
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Searching a Vector
• The methods in the next group are used to search a
vector.
• The contains method searches a vector for a
specified element, returning true if it finds the
element and false otherwise:
if (v.contains("a")) …
Java Programming
FROM THE BEGINNING
57
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Searching a Vector
• The indexOf method searches a vector for a
specified element, returning the index of the
element (or –1 if the element isn’t found).
• One version starts at the beginning of the vector:
index = v.indexOf("a");
// Finds first occurrence of "a" in v
• The other begins its search at a specified index:
index = v.indexOf("a", 10);
// Finds first occurrence of "a"
// in v, starting at position 10
Java Programming
FROM THE BEGINNING
58
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Searching a Vector
• The lastIndexOf method performs a reverseorder search, returning the index of the element
(or –1 if the element isn’t found).
• One version starts at the end of the vector:
index = v.lastIndexOf("a");
// Finds last occurrence of "a" in v
• The other begins its search at a specified index:
index = v.lastIndexOf("a", 10);
// Finds last occurrence of "a"
// in v, starting at position 10
Java Programming
FROM THE BEGINNING
59
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Searching a Vector
• The contains, indexOf, and lastIndexOf
methods use the equals method to test whether
an object in the vector matches the search key.
• For example, two strings will test equal if they
contain the same characters; it’s not necessary for
the references to the strings to match.
Java Programming
FROM THE BEGINNING
60
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Size and Capacity of a Vector
• The methods in the last group are related to the size
and capacity of a vector.
• The capacity method returns the current capacity
of a vector:
int capacity = v.capacity();
• The ensureCapacity method increases the
capacity of a vector, if necessary, to a specified value:
v.ensureCapacity(100);
• If the vector’s current capacity is greater than or equal
to the desired capacity, the method does nothing.
Java Programming
FROM THE BEGINNING
61
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Size and Capacity of a Vector
• The isEmpty method returns true if a vector is
empty (its size is zero) and false otherwise:
if (v.isEmpty()) …
• The setSize method changes the size of a
vector to a specified value:
v.setSize(10);
• If the vector’s current size exceeds the specified
value, the excess elements are lost.
• If the vector’s size is smaller than the specified
value, null values are added at the end.
Java Programming
FROM THE BEGINNING
62
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Size and Capacity of a Vector
• The size method returns the current size of a
vector:
int size = v.size();
• The trimToSize method reduces the capacity
of a vector so it matches the vector’s current size:
v.trimToSize();
• The only reason to use trimToSize is to
conserve memory.
• The best time to call trimToSize is after the
vector has reached its maximum size.
Java Programming
FROM THE BEGINNING
63
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Arrays Versus Vectors
• Factors to consider when choosing between arrays
and vectors:
• Flexibility. Vectors have the edge because they
can grow automatically.
Java Programming
FROM THE BEGINNING
64
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Arrays Versus Vectors
• Ease of use. Arrays are generally easier to use
than vectors.
– Array elements can be selected using square brackets
rather than a method call.
– The elements of a vector must be cast to the proper type
when they are retrieved.
– The elements of an array can be of any type; the
elements of a vector must be objects.
– On the other hand, the Vector class provides useful
methods such as insertElementAt.
Java Programming
FROM THE BEGINNING
65
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Arrays Versus Vectors
• Efficiency.
– If the number of elements is known in advance, arrays
are more space-efficient than vectors.
– If the number of elements isn’t known, an array may be
less efficient, because it will probably be too large.
– Array operations are slightly faster than vector
operations.
– If a vector is resized, however, there will be a time
penalty.
Java Programming
FROM THE BEGINNING
66
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Arrays Versus Vectors
• One drawback of vectors is that there’s no way to
force the elements of a vector to be of the same
type.
• If a program stores objects of the wrong type in a
vector, the compiler won’t be able to detect the
error.
Java Programming
FROM THE BEGINNING
67
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Program: Reversing a Series of Lines
• The ReverseLines program will reverse a
series of lines entered by the user.
• The user will enter any number of input lines,
which the program will store.
• When the user enters a blank line (by pressing the
Enter key without entering any characters on the
line), the program stops accepting input.
• At that point, it will display—in reverse order—
the lines originally entered by the user.
Java Programming
FROM THE BEGINNING
68
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
User Interface
• An example:
Enter lines to be reversed, ending with a blank line.
To be, or not to be: that is the question:
Whether 'tis nobler in the mind to suffer
The slings and arrows of outrageous fortune,
Or to take arms against a sea of troubles,
And by opposing end them? To die: to sleep;
No more; and, by a sleep to say we end
The heartache and the thousand natural shocks
That flesh is heir to, 'tis a consummation
Devoutly to be wish'd. To die, to sleep;
To sleep: perchance to dream: ay, there's the rub;
For in that sleep of death what dreams may come
 user enters a blank line
Java Programming
FROM THE BEGINNING
69
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
User Interface
• An example (continued):
For in that sleep of death what dreams may come
To sleep: perchance to dream: ay, there's the rub;
Devoutly to be wish'd. To die, to sleep;
That flesh is heir to, 'tis a consummation
The heartache and the thousand natural shocks
No more; and, by a sleep to say we end
And by opposing end them? To die: to sleep;
Or to take arms against a sea of troubles,
The slings and arrows of outrageous fortune,
Whether 'tis nobler in the mind to suffer
To be, or not to be: that is the question:
Java Programming
FROM THE BEGINNING
70
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Design of the ReverseLines Program
• ReverseLines can’t begin displaying the
reversed lines until the user has finished entering
the original lines.
• As a result, the program will need to store the
lines (as strings) in a data structure.
• A vector is good choice.
• Using an array would require limiting the number
of lines entered by the user (or having the program
resize the array when it becomes full).
Java Programming
FROM THE BEGINNING
71
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
ReverseLines.java
// Reverses a series of lines entered by the user
import java.util.*;
import jpb.*;
public class ReverseLines {
public static void main(String[] args) {
// Prompt user to enter lines
System.out.println("Enter lines to be reversed, " +
"ending with a blank line.");
// Create vector to hold lines
Vector lines = new Vector();
Java Programming
FROM THE BEGINNING
72
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
// Read lines and store in vector
while (true) {
String inputLine = SimpleIO.readLine();
if (inputLine.length() == 0)
break;
lines.addElement(inputLine);
}
// Display elements of vector in reverse order
for (int i = lines.size() - 1; i >= 0; i--)
System.out.println(lines.elementAt(i));
}
}
Java Programming
FROM THE BEGINNING
73
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
13.3 Wrapper Classes
• The elements of a vector must be objects, which
would seem to rule out a vector of integers or
floating-point numbers.
• Wrapper classes provide a way to get around this
restriction.
• An instance of a wrapper class is an object that
contains a single value of a primitive type.
• Instead of storing an integer into a vector, for
example, an object that contains an integer as its
only instance variable can be stored.
Java Programming
FROM THE BEGINNING
74
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Wrapper Classes
• The wrapper classes belong to the java.lang
package.
• There is a wrapper class for each primitive type:
Primitive Type
boolean
byte
char
double
float
int
long
short
Java Programming
FROM THE BEGINNING
Wrapper Class
Boolean
Byte
Character
Double
Float
Integer
Long
Short
75
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Using Wrapper Classes to Create Objects
• The constructor for a wrapper class will convert a
value of a primitive type into an object.
• Example of converting a double value (stored in
the variable x) into a Double object:
Double d = new Double(x);
• The value can later be retrieved by calling the
doubleValue method:
double y = d.doubleValue();
• Each wrapper class has retrieval methods that
return the stored value upon request.
Java Programming
FROM THE BEGINNING
76
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Using Wrapper Classes to Create Objects
Wrapper Class
Boolean
Byte
Character
Double
Float
Integer
Long
Short
Java Programming
FROM THE BEGINNING
Retrieval Method(s)
booleanValue
byteValue, doubleValue, floatValue,
intValue, longValue, shortValue
charValue
byteValue, doubleValue, floatValue,
intValue, longValue, shortValue
byteValue, doubleValue, floatValue,
intValue, longValue, shortValue
byteValue, doubleValue, floatValue,
intValue, longValue, shortValue
byteValue, doubleValue, floatValue,
intValue, longValue, shortValue
byteValue, doubleValue, floatValue,
intValue, longValue, shortValue
77
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Using Wrapper Classes to Create Objects
• If a value isn’t retrieved in its “natural” form (for
example, if an int value is retrieved from a
Double object), it is cast to the desired type.
Java Programming
FROM THE BEGINNING
78
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Using the Wrapper Classes with Vectors
• Although the elements of a vector can’t belong to a
primitive type, such as double, a vector can store
Double objects instead.
• A statement that stores the value of x in the vector v at
position i:
v.setElementAt(new Double(x), i);
• The doubleValue method can later be used to retrieve
the number:
Double d = (Double) v.elementAt(i);
double y = d.doubleValue();
• The two statements can be combined:
double y = ((Double) v.elementAt(i)).doubleValue();
Java Programming
FROM THE BEGINNING
79
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Other Uses of Wrapper Classes
• Each wrapper class (other than Boolean)
contains constants named MIN_VALUE and
MAX_VALUE, which represent the smallest and
largest values of the corresponding primitive type.
• An example:
– Short.MIN_VALUE is –32768.
– Short.MAX_VALUE is 32767.
• The Double and Float classes also provide
constants named NaN, NEGATIVE_INFINITY,
and POSITIVE_INFINITY.
Java Programming
FROM THE BEGINNING
80
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Other Uses of Wrapper Classes
• Most wrapper classes also provide a class method
that converts a string into a value of the
corresponding primitive type.
• Integer.parseInt is one of these methods.
• Prior to JDK version 1.2, the Double and Float
classes lacked such a method.
• Starting with version 1.2, the Double class
provides a parseDouble method, and the
Float class provides a parseFloat method.
Java Programming
FROM THE BEGINNING
81
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
13.4 Sorting
• One of the most fundamental operations on data is
sorting: putting a list of items in order.
• Examples of sorted lists:
Numbers:
Characters:
Strings:
–53 –38 9 16 45 66 89
0 1 A B a b
aardvark ant anteater bat cat
• In Java, the ordering of characters is based on their
Unicode values.
• Strings are normally sorted into lexicographic
order.
Java Programming
FROM THE BEGINNING
82
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Ascending Order versus
Descending Order
• Data items can be sorted into ascending order
(with smaller values coming before larger ones),
or descending order:
Ascending order: –53 –38 9 16 45 66 89
Descending order: 89 66 45 16 9 –38 –53
• Sorting can be very time consuming if not done
properly.
• Fortunately, a number of good sorting algorithms
are known.
Java Programming
FROM THE BEGINNING
83
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Inserting into a Sorted Array
• An algorithm for inserting items into an empty
array, keeping the items in sorted order at all
times:
1. For all positions in the array, from 0 to n – 1 (where n is
the number of items stored in the array), test whether the
item to be inserted is less than the one stored at position i.
If so, break out of the loop.
2. Insert the new item at position i after moving the items
at positions i through n – 1 down one position.
Java Programming
FROM THE BEGINNING
84
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Inserting into a Sorted Array
• The insertion algorithm expressed in Java:
int i;
for (i = 0; i < n; i++)
if (itemToInsert < a[i])
break;
for (int j = n; j > i; j--)
a[j] = a[j-1];
a[i] = itemToInsert;
n++;
• This algorithm works even if the new item is
larger than all the ones already in the array, or if
the array contains no items at all.
Java Programming
FROM THE BEGINNING
85
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Inserting into a Sorted Array
• If the array contains values other than numbers,
the condition in the if statement will need to be
changed.
• The test condition if a contains strings:
itemToInsert.compareTo(a[i]) < 0
Java Programming
FROM THE BEGINNING
86
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Inserting into a Sorted Array
• The algorithm for inserting items into an array
illustrates an important design principle:
Design an algorithm to work in the typical case.
Then go back and check to see if it correctly
handles the special cases. If it doesn’t, add
additional tests for those cases.
Java Programming
FROM THE BEGINNING
87
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Inserting into a Sorted Array
• Snapshots of an array as the numbers 83, 24, 56,
90, and 17 are inserted:
Java Programming
FROM THE BEGINNING
88
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Insertion Sort
• The idea of inserting a new item into a set of items
that’s already in order can be used to sort an array
even if all the items are already stored in the array
prior to sorting.
• An array a can be sorted by inserting the element
at position i into the ones at positions 0 through i –
1 (which will already be in order).
Java Programming
FROM THE BEGINNING
89
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Insertion Sort
• In other words:
– Insert the element at position 1 into the elements at
positions 0 through 0.
– Insert the element at position 2 into the elements at
positions 0 through 1.
– Insert the element at position 3 into the elements at
positions 0 through 2, and so on.
• This sorting algorithm is known as insertion sort.
Java Programming
FROM THE BEGINNING
90
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Insertion Sort
• The insertion sort algorithm is simpler if the
element to be inserted (the one at position i) is
compared with the elements at positions i – 1, i –
2, …, 0, working backward instead of forward.
• If a comparison indicates that the element to be
inserted is smaller than the one at position j, then
the element at position j can be moved down one
place in the array.
Java Programming
FROM THE BEGINNING
91
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Insertion Sort
• An example that uses insertion sort to sort an array
of five integers:
Shaded elements are not yet in sorted order.
Java Programming
FROM THE BEGINNING
92
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Insertion Sort
• A Java version of insertion sort:
for (int i = 1; i < a.length; i++) {
int itemToInsert = a[i];
int j = i - 1;
while (j >= 0 && itemToInsert < a[j]) {
a[j+1] = a[j];
j--;
}
a[j+1] = itemToInsert;
}
Java Programming
FROM THE BEGINNING
93
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Insertion Sort
• If the array contains values other than numbers,
the condition in the while statement will need to
be changed.
• The while statement if a contains strings:
while (j >= 0 &&
itemToInsert.compareTo(a[j]) < 0) {
…
}
Java Programming
FROM THE BEGINNING
94
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Insertion Sort
• Insertion sort is easy to implement but not very
efficient.
• In the worst case, it performs
1 + 2 + 3 + … + (n – 1) = n(n – 1)/2
comparisons, where n is the number of elements in
the array.
• This number is approximately n2/2, so the time
required to sort grows rapidly as n increases.
Java Programming
FROM THE BEGINNING
95
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Insertion Sort
• Comparisons performed by insertion sort for various
array sizes:
Array
Size
10
100
1,000
10,000
100,000
Number of
Comparisons
45
4,950
499,500
49,995,000
4,999,950,000
• For small arrays, insertion sort is usually fast enough.
• For larger arrays, better algorithms are necessary.
Java Programming
FROM THE BEGINNING
96
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Program: Sorting a Series of Lines
• The SortLines program will sort a series of
lines entered by the user.
• When the user enters a blank line, SortLines
will display the lines entered by the user, sorted
into lexicographic order.
Java Programming
FROM THE BEGINNING
97
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
User Interface
• An example:
Enter lines to be sorted, ending with a blank line.
To be, or not to be: that is the question:
Whether 'tis nobler in the mind to suffer
The slings and arrows of outrageous fortune,
Or to take arms against a sea of troubles,
And by opposing end them? To die: to sleep;
No more; and, by a sleep to say we end
The heartache and the thousand natural shocks
That flesh is heir to, 'tis a consummation
Devoutly to be wish'd. To die, to sleep;
To sleep: perchance to dream: ay, there's the rub;
For in that sleep of death what dreams may come
 user enters a blank line
Java Programming
FROM THE BEGINNING
98
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
User Interface
• An example (continued):
And by opposing end them? To die: to sleep;
Devoutly to be wish'd. To die, to sleep;
For in that sleep of death what dreams may come
No more; and, by a sleep to say we end
Or to take arms against a sea of troubles,
That flesh is heir to, 'tis a consummation
The heartache and the thousand natural shocks
The slings and arrows of outrageous fortune,
To be, or not to be: that is the question:
To sleep: perchance to dream: ay, there's the rub;
Whether 'tis nobler in the mind to suffer
Java Programming
FROM THE BEGINNING
99
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Design of the SortLines Program
• Because the number of lines isn’t known in
advance, a vector would be a good data structure.
• The lines are read one by one, so they can be
inserted into the vector so that it remains sorted at
all times.
• The insertElementAt method will
automatically shift existing elements to make
room for the new one.
Java Programming
FROM THE BEGINNING
100
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
SortLines.java
// Sorts a series of lines entered by the user
import java.util.*;
import jpb.*;
public class SortLines {
public static void main(String[] args) {
// Prompt user to enter lines
System.out.println("Enter lines to be sorted, " +
"ending with a blank line.");
// Create vector to store lines
Vector v = new Vector();
Java Programming
FROM THE BEGINNING
101
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
// Read lines and insert into vector; elements will be
// kept in order at all times
while (true) {
// Read a line; exit loop if line is empty
String inputLine = SimpleIO.readLine();
if (inputLine.length() == 0)
break;
// Determine where line should be stored in vector
int i;
for (i = 0; i < v.size(); i++)
if (inputLine.compareTo((String) v.elementAt(i)) < 0)
break;
// Insert line at this position. Existing elements will
// be moved to make room for the new element.
v.insertElementAt(inputLine, i);
}
Java Programming
FROM THE BEGINNING
102
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
// Display elements of vector
for (int i = 0; i < v.size(); i++)
System.out.println(v.elementAt(i));
}
}
Java Programming
FROM THE BEGINNING
103
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
13.5 Searching
• If the elements of an array (or vector) aren’t in any
particular order, there is no better way to search
for a particular element than sequential search.
• If the elements are sorted, a more efficient
strategy, binary search, becomes possible.
Java Programming
FROM THE BEGINNING
104
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Binary Search
• Suppose that a is a sorted array and key is the
value to be located in the array.
• The binary search algorithm compares key with
the element in the middle of a.
– If key is smaller than the middle element, the
algorithm can limit its search to the first half of a.
– If key is larger, the algorithm searches only the last
half of a.
• This process is repeated until the key is found or
there are no elements left to search.
Java Programming
FROM THE BEGINNING
105
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Binary Search
• The binary search algorithm will use variables
named low and high that keep track of which
array elements are still under consideration.
• A third variable, mid, will indicate the halfway
point between low and high.
Java Programming
FROM THE BEGINNING
106
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Binary Search
• A Java version of the binary search algorithm:
int low = 0;
int high = a.length - 1;
while (low < high) {
int mid = (low + high) / 2;
if (a[mid] < key)
low = mid + 1;
else
high = mid;
}
Java Programming
FROM THE BEGINNING
107
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Binary Search
• If a contains values other than numbers, the
condition in the if statement will need to be
changed.
• If the elements of a are strings, the statement
becomes
if (a[mid].compareTo(key) < 0) …
Java Programming
FROM THE BEGINNING
108
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Binary Search
• If the key is present in the array, the final value of
low indicates its position in the array.
• If the key isn’t known to be present in the array, an
additional test will be needed after the while
loop terminates:
if (a[low] == key)
// Key was found
else
// Key was not found
Java Programming
FROM THE BEGINNING
109
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Binary Search
• A binary search for the number 40:
Java Programming
FROM THE BEGINNING
110
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Binary Search
• Binary search works by repeatedly dividing the
array in half, so it is extremely efficient.
• In the worst case, it performs log2 n comparisons,
rounded up to the nearest integer, where n is the
number of elements in the array.
Java Programming
FROM THE BEGINNING
111
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Binary Search
• The number of comparisons performed by binary
search remains small even for very large values of
n, because log2 n is such a slow-growing function.
Array
Size
10
100
1,000
10,000
100,000
Number of
Comparisons
4
7
10
14
17
Java Programming
FROM THE BEGINNING
112
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Program: Determining Air Mileage
• The AirMileage program will display the air
mileage from New York City to an international
city specified by the user:
This program finds the air mileage between
New York and major international cities.
Enter city name: Oslo
Oslo is 3671 miles from New York City.
Java Programming
FROM THE BEGINNING
113
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Design of the AirMileage Program
• The AirMileage program will store the names
of 36 cities in an array.
• A parallel array will store the distances from New
York to each of the cities in the first array.
• Using binary search to locate the city name
entered by the user will be more efficient than
using sequential search.
Java Programming
FROM THE BEGINNING
114
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
AirMileage.java
// Determines air mileage from New York to other cities.
// Mileages are from The New York Public Library Desk
// Reference, Second Edition (New York: Prentice-Hall, 1993).
import jpb.*;
public class AirMileage {
// Names of international cities
private static final String[] CITY_NAMES =
{"acapulco",
"amsterdam", "antigua",
"aruba",
"athens",
"barbados",
"bermuda",
"bogota",
"brussels",
"buenos aires", "caracas",
"copenhagen",
"curacao",
"frankfurt", "geneva",
"glasgow",
"hamburg",
"kingston",
"lima",
"lisbon",
"london",
"madrid",
"manchester", "mexico City",
"milan",
"nassau",
"oslo",
"paris",
"reykjavik", "rio de janeiro",
"rome",
"san juan",
"santo domingo",
"st. croix",
"tel aviv",
"zurich"};
Java Programming
FROM THE BEGINNING
115
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
// Distances from New York
private static final int[]
{2260, 3639, 1783, 1963,
5302, 2123, 3849, 1993,
3651, 3366, 3456, 3588,
3628, 2600, 4816, 4280,
to other cities
DISTANCES =
4927, 2100, 771,
3851, 3859, 3211,
3336, 2086, 4004,
1609, 1560, 1680,
2487,
3806,
1101,
5672,
3662,
1583,
3671,
3926};
public static void main(String[] args) {
// Display initial message
System.out.println(
"This program finds the air mileage between\n" +
"New York and major international cities.\n");
// Prompt user for city name
SimpleIO.prompt("Enter city name: ");
String cityName = SimpleIO.readLine().trim();
Java Programming
FROM THE BEGINNING
116
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
// Use binary search to locate name in CITY_NAMES array
int i = binarySearch(CITY_NAMES, cityName.toLowerCase());
// If name was found in array, display distance from New
// York to chosen city
if (cityName.equalsIgnoreCase(CITY_NAMES[i]))
System.out.println(cityName + " is " + DISTANCES[i] +
" miles from New York City.");
else
System.out.println(cityName + " wasn't found.");
}
Java Programming
FROM THE BEGINNING
117
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
// Uses the binary search algorithm to locate key in the
// array a. Returns the index of key if it is found in a.
private static int binarySearch(String[] a, String key) {
int low = 0;
int high = a.length - 1;
while (low < high) {
int mid = (low + high) / 2;
if (a[mid].compareTo(key) < 0)
low = mid + 1;
else
high = mid;
}
return low;
}
}
Java Programming
FROM THE BEGINNING
118
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
13.6 Sets
• In mathematics, a set is an unordered collection of
values, with no duplicates.
• Sets are usually enclosed in curly braces.
• For example, {3, 9, 11} would be a set consisting
of three elements: 3, 9, and 11.
Java Programming
FROM THE BEGINNING
119
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Properties of Sets
• Sets are just as useful to programmers as they are
to mathematicians.
• Properties of sets:
– Have no duplicate elements.
– Elements don’t have to be stored in any particular order.
– Operations are different from those on other data
structures.
Java Programming
FROM THE BEGINNING
120
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Operations on Sets
• Typical set operations:
– Storing a value into a set. If the value is already an
element of the set, this operation has no effect.
– Removing a value from a set. If the value is not an
element of the set, this operation has no effect.
– Testing whether a value belongs to a set.
– Computing the union of two sets (the set of all elements
that belong to either, or both, of the sets).
– Computing the intersection of two sets (the set of all
elements that belong to both sets).
Java Programming
FROM THE BEGINNING
121
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Applications of Sets
• A program that plays a card game could use a set
to keep track of which cards are in a player’s hand.
• A program that works with English text could use
a set to keep track of which letters appear in a
word or sentence.
Java Programming
FROM THE BEGINNING
122
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Bit Sets
• Java provides a BitSet class, whose instances
(bit sets) can be used to represent sets.
• BitSet belongs to the java.util package.
• A bit set behaves like a vector whose elements are
boolean values.
• By setting some of the elements of a bit set to
true and the others to false, it can be used to
keep track of the elements in a set.
Java Programming
FROM THE BEGINNING
123
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Bit Sets
• Consider the set of all positive integers no larger
than 15 that are divisible by 2.
• In mathematical notation, this set would be written
{2, 4, 6, 8, 10, 12, 14}
• A bit set that corresponds to this set:
• Each element of a bit set has an integer index,
starting at 0.
Java Programming
FROM THE BEGINNING
124
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Bit Sets
• The set of positive integers no larger than 15 that
are divisible by 3 is
{3, 6, 9, 12, 15}
• The corresponding bit set:
Java Programming
FROM THE BEGINNING
125
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Bit Sets
• Advantages of bit sets:
– A bit set requires much less memory than an array or
vector of boolean values, because each element is
stored as a single bit.
– A bit set will automatically increase its size as needed.
Java Programming
FROM THE BEGINNING
126
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Bit Sets
• The BitSet class has two constructors.
• One constructor takes a single int argument,
specifying the number of bits in the set:
BitSet multiplesOf2 = new BitSet(16);
BitSet multiplesOf3 = new BitSet(16);
• In a newly created bit set, all bits have the value
false.
Java Programming
FROM THE BEGINNING
127
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Bit Sets
• The set method changes a single bit to true:
multiplesOf2.set(2);
multiplesOf2.set(4);
multiplesOf2.set(6);
multiplesOf2.set(8);
multiplesOf2.set(10);
multiplesOf2.set(12);
multiplesOf2.set(14);
multiplesOf3.set(3);
multiplesOf3.set(6);
multiplesOf3.set(9);
multiplesOf3.set(12);
multiplesOf3.set(15);
Java Programming
FROM THE BEGINNING
128
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Bit Sets
• Other basic operations on bit sets:
– Clearing a bit
– Retrieving the value of a bit
• The clear method “clears” a bit by setting it to
false:
multiplesOf2.clear(2);
• The get method returns the value stored at a
specific bit position:
if (multiplesOf2.get(2)) …
Java Programming
FROM THE BEGINNING
129
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Bit Sets
• Bit sets support three Boolean operations: and, or,
and exclusive or.
• These operations correspond to the set operations
of intersection, union, and symmetric difference.
• The symmetric difference of two sets is the set of
all elements that belong to one set but not the
other.
• The BitSet methods that perform Boolean
operations modify the calling object rather than
returning a new bit set.
Java Programming
FROM THE BEGINNING
130
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Bit Sets
• The and method combines two bit sets by
performing a logical and operation on all
corresponding bits in the sets.
• A call of the and method:
multiplesOf2.and(multiplesOf3);
multiplesOf2 will be modified so that it has
true values only in positions 6 and 12.
Java Programming
FROM THE BEGINNING
131
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Bit Sets
• The or method performs a logical or operation on
two bit sets.
• A call of the or method:
multiplesOf2.or(multiplesOf3);
The resulting set will have true values in
positions 2, 3, 4, 6, 8, 9, 10, 12, 14, and 15.
Java Programming
FROM THE BEGINNING
132
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Bit Sets
• The xor method produces a true result only in
those positions where one of the original sets (but
not both) has a true value.
• A call of the xor method:
multiplesOf2.xor(multiplesOf3);
The resulting set will have true values in
positions 2, 3, 4, 8, 9, 10, 14, and 15.
Java Programming
FROM THE BEGINNING
133
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Program: Finding Primes Using
the Sieve of Eratosthenes
• The Greek mathematician Eratosthenes devised an efficient
way to find prime numbers, known as the sieve of
Eratosthenes.
• A pencil-and-paper version:
– Write down the integers from 2 to some maximum value.
– Cross off every second number after 2.
– Look for the first number after 2 that wasn’t crossed off (3,
in this case) and cross off all multiples of 3, starting at 6.
• By repeating the process enough times, all non-primes
would be crossed off, leaving only the primes:
Java Programming
FROM THE BEGINNING
134
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Design of the Sieve Program
• The Sieve program is a Java implementation of
the sieve of Eratosthenes.
• In Java, a bit set can be used to keep track of
which numbers have been crossed off.
• Initially, all bits at positions 2 and higher will be
set, indicating that these numbers are potential
primes. (Positions 0 and 1 will be ignored.)
• “Crossing off” a number will consist of clearing
the corresponding bit.
Java Programming
FROM THE BEGINNING
135
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Sieve.java
// Finds primes using the sieve of Eratosthenes
import java.util.*;
import jpb.*;
public class Sieve {
public static void main(String[] args) {
// Prompt user to enter a bound on the largest prime
SimpleIO.prompt("Enter bound on largest prime: ");
String userInput = SimpleIO.readLine().trim();
int bound = Integer.parseInt(userInput);
// Create a bit set; bits 0 and 1 will not be used
BitSet primes = new BitSet(bound + 1);
// Set all bits, starting at position 2
for (int i = 2; i <= bound; i++)
primes.set(i);
Java Programming
FROM THE BEGINNING
136
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
// Clear bits that correspond to multiples of a prime
for (int i = 2; i * i <= bound; i++)
if (primes.get(i))
for (int j = 2 * i; j <= bound; j += i)
primes.clear(j);
// Display all numbers whose bits are still set
System.out.println("Primes: " + primes);
}
}
Java Programming
FROM THE BEGINNING
137
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Discussion of the Sieve Program
• Any number that isn’t prime must have a divisor
that’s no larger than its square root.
• This fact makes it possible to use the condition
i * i <= bound to control the second for
statement, instead of a less efficient test such as
i <= bound.
Java Programming
FROM THE BEGINNING
138
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Discussion of the Sieve Program
• Output of the Sieve program:
Enter bound on largest prime: 25
Primes: {2, 3, 5, 7, 11, 13, 17, 19, 23}
• The call of System.out.println implicitly
uses the toString method to convert the
primes bit set into a string.
• toString returns a string containing the
contents of a bit set in mathematical notation.
Java Programming
FROM THE BEGINNING
139
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
13.7 The StringBuffer Class
• String objects are immutable: once a String
object has been created, the characters in it can
never be changed.
• A StringBuffer object (or string buffer) is
similar to a String object, except that its
characters can be changed.
Java Programming
FROM THE BEGINNING
140
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Buffers
• In the computing field, a buffer is a place where
data is stored temporarily, usually on its way from
one place to another.
• A string buffer is a temporary place to store a
string as it’s being changed.
• Changing a String object requires three steps:
– Converting it to a string buffer.
– Changing the characters in the string buffer.
– Converting the buffer back to a String object.
Java Programming
FROM THE BEGINNING
141
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Properties of String Buffers
• A string buffer behaves like a vector of characters.
• Each string buffer has a capacity—the maximum
number of characters it can store.
• If an operation on the buffer causes the capacity to
be exceeded, the capacity is increased
automatically.
• The StringBuffer class belongs to the
java.lang package.
Java Programming
FROM THE BEGINNING
142
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Creating a String Buffer
• Examples of using StringBuffer constructors:
StringBuffer stringBuf1 = new StringBuffer();
StringBuffer stringBuf2 = new StringBuffer(100);
StringBuffer stringBuf3 =
new StringBuffer("antidisestablishmentarianism");
• strBuf1 will have a capacity of 16 characters.
• The capacity of strBuf2 will be 100, and the
capacity of strBuf3 will be 28 + 16 = 44.
• strBuf1 and strBuf2 are currently empty.
• strBuf3 contains
antidisestablishmentarianism.
Java Programming
FROM THE BEGINNING
143
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Operations on String Buffers
• Primary operations on a string buffer:
– Appending: Adding characters to the end of the string
that’s currently stored in the string buffer.
– Inserting: Moving some of the characters already in the
string and then putting additional characters in the
middle of the string.
• Both operations will automatically increase the
capacity of the buffer if necessary.
Java Programming
FROM THE BEGINNING
144
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Appending to a String Buffer
• Appending is done by calling the append method.
• There are 10 different versions of append, but
they’re all similar.
• Almost any kind of data can be appended, including a
string, a value of a primitive type, or an object:
StringBuffer stringBuf = new StringBuffer();
stringBuf.append("abc");
// stringBuf now contains "abc"
stringBuf.append(123);
// stringBuf now contains "abc123"
• If the data to be appended isn’t a string, append will
automatically convert it to string form.
Java Programming
FROM THE BEGINNING
145
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Appending to a String Buffer
• The append method returns the string buffer on
which the operation was performed.
• This property makes it possible to chain together a
series of append calls:
stringBuf.append("abc").append(123);
Java Programming
FROM THE BEGINNING
146
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Appending to a String Buffer
• The + operator is actually a shorthand notation for
the append method.
• The statement
str = str1 + str2 + str3;
is equivalent to
StringBuffer stringBuf = new StringBuffer();
stringBuf.append(str1).append(str2).append(str3);
str = stringBuf.toString();
Java Programming
FROM THE BEGINNING
147
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
The toString Method
• The toString method can be used to convert a
string buffer back to ordinary string form.
• To print the contents of a string buffer, it’s not
necessary to call toString explicitly; the
System.out.print and
System.out.println methods will
automatically call toString.
Java Programming
FROM THE BEGINNING
148
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Inserting into a String Buffer
• The insert methods that StringBuffer provides
are similar to the append methods.
• Most versions of insert require two arguments:
– An “offset” in the string buffer
– The data item to be inserted
• After the insertion, the first character of this item will
occupy the specified offset:
StringBuffer stringBuf = new StringBuffer("TH8");
stringBuf.insert(2, "X");
// stringBuf now contains "THX8"
stringBuf.insert(3, 113);
// stringBuf now contains "THX1138"
Java Programming
FROM THE BEGINNING
149
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Inserting into a String Buffer
• Any kind of data can be inserted into a string buffer,
including values of primitive types as well as objects.
• insert returns the string buffer on which the
operation was performed, which allows chaining:
stringBuf.insert(2, "X").insert(3, 113);
• insert throws
StringIndexOutOfBoundsException if the
offset is less than 0 or greater than the length of the
string stored in the string buffer.
Java Programming
FROM THE BEGINNING
150
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Inserting into a String Buffer
• Inserting at the end of a string is legal:
StringBuffer stringBuf = new StringBuffer("abc");
stringBuf.insert(3, "d");
// stringBuf now contains "abcd"
Java Programming
FROM THE BEGINNING
151
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Other String Buffer Operations
• The other major operations on a string buffer are
accessing a character and changing a character.
• The charAt method returns the character at a
specified position in a string buffer:
char ch = stringBuf.charAt(2);
• The setCharAt method stores a character into a
string buffer at a specified position:
stringBuf.setCharAt(2, 'a');
Java Programming
FROM THE BEGINNING
152
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Length and Capacity of a String Buffer
• Other StringBuffer methods are related to the
length and capacity of a string buffer.
• The capacity method returns the current capacity
of a string buffer:
int capacity = stringBuf.capacity();
• The ensureCapacity method increases the
capacity of a string buffer, if necessary, to a specified
value:
stringBuf.ensureCapacity(100);
• If the buffer’s current capacity is greater than or equal
to the desired capacity, the method does nothing.
Java Programming
FROM THE BEGINNING
153
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Length and Capacity of a String Buffer
• The length method returns the current length of the
string stored in a string buffer:
int length = stringBuf.length();
• The setLength method changes the length of a
string buffer:
stringBuf.setLength(10);
• If the length of the string that’s currently stored in the
buffer is larger than the specified value, characters are
removed from the end of the string.
• If the string’s length is smaller than the specified
value, null characters are added to the end.
Java Programming
FROM THE BEGINNING
154
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Program: Sorting the
Characters in a String
• The SortCharacters program will prompt the
user to enter a string of characters and then print the
sorted version of those characters:
Enter a string: folderol
Sorted version of string: deflloor
• The input will be stored in a string that can’t be
changed directly, so a string buffer will be needed.
• The program will fetch characters one by one from the
original string and insert them into the string buffer,
using the algorithm from the SortLines program.
Java Programming
FROM THE BEGINNING
155
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
SortCharacters.java
// Sorts the characters in a string
import jpb.*;
public class SortCharacters {
public static void main(String[] args) {
// Prompt user to enter a string
SimpleIO.prompt("Enter a string: ");
String userInput = SimpleIO.readLine();
// Create a string buffer to hold the sorted string
StringBuffer stringBuf = new StringBuffer();
Java Programming
FROM THE BEGINNING
156
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
// Insert characters from the user's input into the
// string buffer, keeping the characters in the buffer
// sorted at all times
for (int i = 0; i < userInput.length(); i++) {
char ch = userInput.charAt(i);
int j;
for (j = 0; j < stringBuf.length(); j++)
if (ch < stringBuf.charAt(j))
break;
stringBuf.insert(j, ch);
}
// Display contents of string buffer
System.out.println("Sorted version of string: " +
stringBuf);
}
}
Java Programming
FROM THE BEGINNING
157
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
13.8 Case Study: Finding Anagrams
• Sorting can be used to solve a surprising number
of problems, including the problem of finding
anagrams in a list of words.
• An anagram of a word is a permutation of the
letters in that word; for example, stop is an
anagram of tops.
Java Programming
FROM THE BEGINNING
158
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Program Behavior
• The FindAnagrams program will prompt the
user to enter a series of words and then determine
which words in the list are anagrams of each other.
• The program will repeatedly prompt the user to
enter words; input stops when the user presses the
Enter key without entering a word.
• The program will then display the words, with
anagrams grouped together on the same line.
Java Programming
FROM THE BEGINNING
159
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Program Behavior
• An example:
Enter
Enter
Enter
Enter
Enter
Enter
Enter
a
a
a
a
a
a
a
word:
word:
word:
word:
word:
word:
word:
pans
pots
opt
snap
stop
tops
Anagrams:
--------1. pans snap
2. pots stop tops
3. opt
Java Programming
FROM THE BEGINNING
160
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Program Behavior
• The FindAnagrams program will ignore
punctuation in a word (it’s is an anagram of sit)
• The program will also ignore the case of letters in
a word (Pots, STOP, and tops are anagrams).
Java Programming
FROM THE BEGINNING
161
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Signatures
• The secret to writing the FindAnagrams
program is use sorting.
• To test whether two words are anagrams, the
program can compute the “signature” of each
word by sorting its letters, and check whether the
signatures are equal.
• For example, the signature of pans is anps, and the
signature of snap is also anps.
Java Programming
FROM THE BEGINNING
162
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Signatures
• A table of words and their signatures:
Word
pans
pots
opt
snap
stop
tops
Signature
anps
opst
opt
anps
opst
opst
• Uppercase letters are converted to lowercase
before the signature is computed.
• Punctuation marks are ignored.
Java Programming
FROM THE BEGINNING
163
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Signatures
• To determine which words are anagrams, the lines
in the table can be sorted by their signatures:
Word
pans
snap
pots
stop
tops
opt
Signature
anps
anps
opst
opst
opst
opt
Java Programming
FROM THE BEGINNING
164
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Signatures
• The last step is to make a pass over the table from
top to bottom.
• Words that have the same signature are anagrams,
so they will be printed on the same line:
pans snap
pots stop tops
opt
Java Programming
FROM THE BEGINNING
165
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Design of the FindAnagrams Program
• The FindAnagrams program will store the
words and their signatures in parallel vectors
named words and signatures.
• An alternative would be to define a new class
whose instances contain both a word and its
signature, and then store those objects in a single
vector.
Java Programming
FROM THE BEGINNING
166
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Design of the FindAnagrams Program
• The program can be divided into two steps:
1. Read words from the user, storing the words into the
words vector and the signatures of the words into the
signatures vector.
2. Print the words in the words vector, putting words that
are anagrams of each other on the same line.
• These steps will be performed by class methods
named readWords and printAnagrams.
Java Programming
FROM THE BEGINNING
167
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Design of the readWords Method
• Pseudocode for readWords:
while (true) {
Prompt the user to enter a word; return if the word is
empty;
Compute the signature of the word;
Determine where the signature belongs in the
signatures vector;
Insert the signature into the signatures vector;
Insert the word at the corresponding location in the
words vector;
}
Java Programming
FROM THE BEGINNING
168
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Design of the printAnagrams Method
• Pseudocode for printAnagrams:
Return if the signatures vector is empty;
Print a heading, followed by the first word in the words
vector;
Print the remaining words in the words vector, placing
words on the same line if they have the same signature;
Java Programming
FROM THE BEGINNING
169
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
Design of the computeSignature Method
• Pseudocode for computeSignature, a helper
method that computes the signature of a word:
Create a new string buffer;
for (int i = 0; i < word.length(); i++) {
Extract the character at position i in word;
If the character is not a letter, ignore it; otherwise,
convert it to lowercase;
Insert the character into the string buffer, keeping the
characters in the buffer sorted at all times;
}
Convert the string buffer into a string and return it;
Java Programming
FROM THE BEGINNING
170
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
FindAnagrams.java
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
Program name: FindAnagrams
Author: K. N. King
Written: 1998-08-19
Prompts the user to enter a series of words. When the
user presses the Enter key without entering a word, the
program will then display the original words, with
anagrams displayed on the same line.
When determining whether two words are anagrams, the
program will ignore punctuation and the case of the
letters in the words.
To find anagrams, the program computes a "signature" for
each word, consisting of the letters in the word after
they have been sorted. The words and their signatures are
stored in parallel vectors, sorted by signature. After
all words have been read, anagrams are located by
looking for identical signatures. Because the signatures
are sorted, identical signatures must be adjacent in the
signatures vector.
Java Programming
FROM THE BEGINNING
171
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
import java.util.*;
import jpb.*;
public class FindAnagrams {
private static Vector words = new Vector();
private static Vector signatures = new Vector();
public static void main(String[] args) {
readWords();
printAnagrams();
}
Java Programming
FROM THE BEGINNING
172
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
///////////////////////////////////////////////////////////
// NAME:
readWords
// BEHAVIOR:
Repeatedly prompts the user to enter words,
//
stopping when the user enters an empty
//
word. Computes the signature of each word,
//
storing the signature in the signatures
//
vector in such a way that the vector is
//
always sorted in ascending order. Stores
//
each word in the words vector at the same
//
position as the signature in the
//
signatures vector.
// PARAMETERS: None
// RETURNS:
Nothing
///////////////////////////////////////////////////////////
private static void readWords() {
while (true) {
// Prompt the user to enter a word; return if the word
// is empty
SimpleIO.prompt("Enter a word: ");
String word = SimpleIO.readLine().trim();
if (word.length() == 0)
return;
Java Programming
FROM THE BEGINNING
173
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
// Compute the signature of the word
String signature = computeSignature(word);
// Determine where the signature belongs in the
// signatures vector
int i;
for (i = 0; i < signatures.size(); i++) {
String signatureInVector =
(String) signatures.elementAt(i);
if (signature.compareTo(signatureInVector) < 0)
break;
}
// Insert the signature into the signatures vector.
// Insert the word at the corresponding location in the
// words vector.
signatures.insertElementAt(signature, i);
words.insertElementAt(word, i);
}
}
Java Programming
FROM THE BEGINNING
174
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
///////////////////////////////////////////////////////////
// NAME:
printAnagrams
// BEHAVIOR:
Prints the contents of the words vector,
//
putting words that are anagrams of each
//
other on the same line. Uses the signatures
//
vector to determine which words are
//
anagrams. Assumes that the i-th element of
//
the signatures vector is the signature of
//
the i-th word in the words vector. Also
//
assumes that the elements of the signatures
//
vector are in sorted order.
// PARAMETERS: None
// RETURNS:
Nothing
///////////////////////////////////////////////////////////
private static void printAnagrams() {
int anagramNumber = 1;
int signatureCount = signatures.size();
Java Programming
FROM THE BEGINNING
175
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
// Return if the signatures vector is empty
if (signatureCount == 0)
return;
// Print a heading, followed by the first word in the
// words vector
System.out.println("\nAnagrams:\n---------");
System.out.print("1. " + words.firstElement());
}
// Print the remaining words in the words vector, placing
// words on the same line if they have the same signature
for (int i = 1; i < signatureCount; i++) {
if (signatures.elementAt(i).equals
(signatures.elementAt(i-1)))
System.out.print(" ");
else
System.out.print("\n" + ++anagramNumber + ". ");
System.out.print(words.elementAt(i));
}
System.out.println();
Java Programming
FROM THE BEGINNING
176
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
///////////////////////////////////////////////////////////
// NAME:
computeSignature
// BEHAVIOR:
Computes the signature of a word by sorting
//
the letters in the word. Characters other
//
than letters are ignored, and uppercase
//
letters are converted to lowercase.
// PARAMETERS: word - the word whose signature is to be
//
computed
// RETURNS:
String object containing the same letters
//
as the original word, but in sorted order
///////////////////////////////////////////////////////////
private static String computeSignature(String word) {
// Create a new string buffer
StringBuffer stringBuf = new StringBuffer(word.length());
Java Programming
FROM THE BEGINNING
177
Copyright © 2000 W. W. Norton & Company.
All rights reserved.
Chapter 13: Data Structures
for (int i = 0; i < word.length(); i++) {
// Extract the character at position i in word.
// If the character is not a letter, ignore it;
// otherwise, convert it to lowercase.
char ch = word.charAt(i);
if (!Character.isLetter(ch))
continue;
ch = Character.toLowerCase(ch);
}
}
}
// Insert the character into the string buffer, keeping
// the characters in the buffer sorted at all times
int j;
for (j = 0; j < stringBuf.length(); j++)
if (ch < stringBuf.charAt(j))
break;
stringBuf.insert(j, ch);
// Convert the string buffer into a string and return it
return stringBuf.toString();
Java Programming
FROM THE BEGINNING
178
Copyright © 2000 W. W. Norton & Company.
All rights reserved.