 |
Improving searching
|
Improving searching - Self Organizing Vectors
-
The search we did previously is inefficient
-
on average, if there are n elements in the vector, we must visit
n/2 elements to find the one we want.
-
In some cases, there are elements that are more frequently requested than
others
-
in the cipher from assignment 5, we might look for the vowels more often
-
in a shop containing 2000 items, the most popular 100 items might be requested
90% of the time
-
In the latter case (and a variety of others were there is a large amount
of data), the search becomes inefficient
Organizing vectors
-
To make searching more efficient, we can organize the objects
-
move most frequently requested items to the front of the Vector so that
we don't have to potentially look over the whole vector for them
-
if we know the order beforehand, we could organize the vector prior to
searching.
-
but sometimes, we don't know the most popular items until they are requested
most often
-
This means we need to move them to the front as we look for them, so that
the next time we look for them, they're toward the front
-
How can we move an element to the front of a vector? E.g. moving 10 the
front of 2 3 4 5 6 7 8 9 10 23 12
-
insert 10 in the front of the vector
-
remove it from where it was
-
Two methods for Vector help us to do this:
-
insertElementAt (Object element, int position) - insert element
at position in the Vector
-
removeElementAt (int position) - delete the element at position
in the Vector
-
If the element we wish to move is at position k, we can insert it in front
by:
v.insertElementAt (v.elementAt (k),0);
Note that the element at k is now at position k+1 - we need to remove it.
v.removeElementAt (k+1);
We can write a method that contains these two instructions so that every
time we want to move an object to the front, we call this helper method
private void moveToFront (Vector v, int k) {
v.insertElementAt (v.elementAt (k), 0);
v.removeElementAt (k+1);
}
We can then modify the search method to move the item to the front once
it is found, so that, if it is requested again, we don't have to look so
far
public int search (String s) {
int k = 0;
while (!(k==v.size () || s.equals (v.elementAt (k)))) {
k++;
}
if (k==v.size ()) {
return -1;
} else {
moveToFront (v,k);
return 1;
}
}
Is this better?
-
Suppose we have 10 elements A, B, C, D, E, F, G, H, I, J stored in a Vector
and the most frequently requested letters are D, G, I with A, E occurring
occasionally. In fact, let's look at the request sequence DDGI DIID GADI
EDGG
| Item sought |
Vector |
# pos checked |
Vector |
#pos checked |
| D |
ABCDEFGHIJ |
4 |
ABCDEFGHIJ |
4 |
| D |
DABCEFGHIJ |
1 |
ABCDEFGHIJ |
4 |
| G |
DABCEFGHIJ |
7 |
ABCDEFGHIJ |
7 |
| I |
GDABCEFHIJ |
9 |
ABCDEFGHIJ |
9 |
| D |
IGDABCEFHJ |
3 |
ABCDEFGHIJ |
4 |
| I |
DIGABCEFHJ |
2 |
ABCDEFGHIJ |
9 |
| I |
IDGABCEFHJ |
1 |
ABCDEFGHIJ |
9 |
| D |
IDGABCEFHJ |
2 |
ABCDEFGHIJ |
4 |
| G |
DIGABCEFHJ |
3 |
ABCDEFGHIJ |
7 |
| A |
GDIABCEFHJ |
4 |
ABCDEFGHIJ |
1 |
| D |
AGDIBCEFHJ |
3 |
ABCDEFGHIJ |
4 |
| I |
DAGIBCEFHJ |
4 |
ABCDEFGHIJ |
9 |
| E |
IDAGBCEFHJ |
7 |
ABCDEFGHIJ |
5 |
| D |
EIDAGBCFHJ |
3 |
ABCDEFGHIJ |
4 |
| G |
DEIAGBCFHJ |
5 |
ABCDEFGHIJ |
7 |
| G |
GDEIABCFHJ |
1 |
ABCDEFGHIJ |
7 |
| TOTAL |
|
56 |
|
94 |
-
-
Note that the change we have made is hidden from anyone using search.
-
we have not changed the behaviour of search, just its implementation
-
In fact, this is part of what makes computer science interesting - trying
to find more efficient ways of doing things
Last modified: 4/5/99