 |
Indexing and Searching
|
Indexing - Another Way To Access Objects in a Vector
-
Vector defines the methods:
-
int size () - number of elements
-
Object elementAt (int index) - return ith element
import cucs.*;
import java.util.*;
...
Vector messages = new Vector ();
BasicDataReader inFile = new BasicDataReader ("mydata.txt");
while (!inFile.eof ())
messages.addElement (inFile.readLine());
...
String tmp;
int s = messages.size();
int i = 1;
while (i <= s) {
tmp = (String) messages.elementAt (i);
System.out.println (tmp);
}
Why have enumerations and indexing?
-
Indexing can be more efficient than using Enumerations
-
Suppose we have a Vector of houses, sorted by price.
-
if a Vector has n houses, how can we find the median mark?
-
enumerations: traverse through n/2 times,
-
indexing: just access the element at position n/2
-
We have no control over the order in which we visit elements (for a Vector,
it is always going to be the first, followed by the second, and so on until
we reach the last).
-
Suppose we want to read in some lines from a file, and print the lines
in reverse order
class ReverseLines {
public static void main (String [] args) {
Vector v = new Vector ();
BasicDataReader in = new BasicDataReader ();
while (!in.eof ()) {
v.addElement (in.readLine ());
}
...
-
To traverse this using enumerations, we have only one possibility
...
Enumeration enum = v.elements ();
while (enum.hasMoreElements ()) {
System.out.println (enum.nextElement ());
}
The above code will print them out in the order they were added.
This problem can be resolved using elementAt
Informal procedure: Print out the element at the last position,
then the second to last, etc until we reach the element at position 0.
Choosing and defining variables: Need to keep track of position
we are up to. This will be an int:
int k; // k == the index of the next position to visit
// Positions v.size ()-1, v.size()-2,..., k_1 have been printed
// Positions k, k-1, ..., 0 are yet to be printed
The while condition: We have finished when all elements have been
printed. This occurs when k reaches -1 (when k is 0, we still have the
element at position 0 to print).
while (k != -1) {...}
Initialization: k needs to be set initially to the index of the
last element, which is v.size ()-1.
Guaranteeing termination: k must approach -1 with each iteration
for the loop to finish. Thus, we need to decrement k by 1.
Completing the loop body: Each time through the loop, we need to
print the next line.
int k = v.size ()-1;
while (k != -1) {
System.out.println (v.elementAt (k));
k -= 1;
}
Searching
-
One common activity is to search for a particular value
-
a bank record associated with a particular customer
-
a web page that has been requested
-
the product associated with an inventory number
-
When we wrote the Set class, we were looking for an element that in a set
to see if the set contained it.
-
Often, it is desirable to return the position that an element was found
in the vector
-
e.g., for the code in assignment 5, we we looking for the position of a
particular character in the code because we used that position to map to
the actual character
-
What happens if something is not found?
-
A common convention is to return -1
-
Let's write a method that searches through a vector of strings for a particular
string, and returns the position in the vector where that string is, an
-1 if it isn't in the vector.
public int search (String s) {...}
// Returns the index of a match to s in v, or -1 if no match is found
Informal procedure: We need to check every element until we find
a match, or until there are no more elements left. We can start at the
first element and proceed to the next.
Choosing and defining variables: We need to keep track of our current
position
The while condition: There are two conditions when we are finished:
-
there are no more elements to visit, or
-
if k==v.size (), we know we haven't found a match
-
we have found a match
-
if we've found a match, we know that k contains the position of the match
in the vector
We are therfore finished when k==v.size () || s.equals (v.elementAt (k))
However, we continue this loop when this is not the case, i.e.,
while (!(k==v.size () || s.equals (v.elementAt (k)))) {
...
}
When we finish this loop, we need to know what to return, because on or
the other of the above conditions may be true (we may have reached the
end, in which case the string isn't found, or we may have found a match).
Thus, we need to choose whether to return k or -1.
if (k == v.size ())
return -1;
else
return k;
Initialization: k needs to point to the index of the next element
to check, which before the loop is 0. Thus, k needs to be initialized to
0
Guaranteeing termination: By incrementing k by 1, we know that k
will eventually equal v.size() or the position of match.
Completing the loop body: Our body is already complete. Nothing
is violated. Each time through the loop, we increment k, and the condition
checks whether a match is found.
public int search (String s) {
int k = 0;
while (!(k==v.size () || s.equals (v.elementAt (i)))) {
k += 1;
}
if (k==v.size ()) {
return -1;
} else {
return k;
}
}
Exercise:
Rewrite the search method so that it starts its search at the end of the
Vector and searches backward toward position 0. When would this be useful?
Last modified: 4/5/99