15-100 Lecture 24 (Wednesday March 23, 2004)

The class that was used today is here. Additionally, the tests taken last friday were returned in class. If you didn't get your test go to Kesden's office hours and you can pick it up there.
Filtering ... continued
Last class we started going over what filtering was, but we didn't finish writing some code for actual filter methods. Today we'll finish up talking about filter methods by writing code for the two types that we talked about last class, and then discussing and coding up a third version.

First Version

The first version of a filter method that we talked about last class was a filter method that started at the begining and moved toward the end of the list. So we have the general idea of this methods, we're just going to have to add some specifics about how exactly this method is going to work. So we already know two things about the method that we're going to write. Its going to walk through the list that we have, position by position, and that its going to start at the begining of the previous list. Now, we just have to decide what the method's doing at each position. In order to do this we have to make a couple more decisions about how we want the filter method to work, namely whether we want the elements that are greater or less then the given element. In this case we'll take the elements that are greater then the given element. Since this is the case we'll check the element at each position and if it's greater then the given element we'll add it to the list. Now its time to code. // remember to talk about time to write start at end/begin

``````
/*
This class filters the array holding the names, and
returns a new SortedNames holding only names greater then the
name passed in
*/
public SortedNames getGreaterThanForward (String name){

//creates the new SortedNames, which the names
//that satisfy the filter will be added to
SortedNames bigNames = new SortedNames(name.length);

//goes through each position in the array
for(int index = 0; index < count index ++){

//if current position passes filter criteria
if(names[index].compareTo(name)>0){
bigNames.insert(names[index]);
}
}

//returns the list of names that was created
return bignames;
}
``````

While we're thinking about this method, what changes would we have to make to the method above if we decided to filter for the names that were less then the given name, instead of greater then?

Because of the way that our class is set up the only thing that we would have to change is to the if statement inside the for loop. Change "if(names[index].compareTo(name)>0)" to "if(names[index].compareTo(name)<0)" and you'll switch the filter.

Second Version of the Filter

In the second version of a filter method we're going to start at the end of the array and work our way forward. Think of what types of changes we might have to make to the method that we previously wrote, if we make this change. Looking over the method, it turns out that the only change that we'll have to make is in the for loop. So a filter method that starts at the end of the list and works its way forward would look like the method below.

``````
/*
This class filters the array holding the names, and
returns a new SortedNames holding only names greater then the
name passed in
*/
public SortedNames getGreaterThanReverse (String name){

//creates the new SortedNames, which the names
//that satisfy the filter will be added to
SortedNames bigNames = new SortedNames(name.length);

//goes through each position in the array
//!!only change in the method is on the line below!!
for(int index = (count -1); index >= 0; index --){

//if current position passes filter criteria
if(names[index].compareTo(name)>0){
bigNames.insert(names[index]);
}
}

//returns the list of names that was created
return bignames;
}
``````

Third Version of the Filter

The third version of the filter is going to work very differently from the first two versions. This version is going to involve some binary searching. If you need to review binary search look at Lecture 24 where its first introduced.

In this version we're going to deal with the problem of sometimes having to look at a whole bunch of items that we don't want. Instead of doing that we'll write a filter method that uses a binary search like method to find the approximate position of where the elements we want start. That way we can then write our filter method, starting from that position.

What does using the binary search like method to find our starting position get us? Since binary search works a lot more efficiently then just going through the items one by one we'll have to look at a lot fewer of the items that we don't want to add to our list. This in turn will allow our method to run faster then it might have otherwise.

In order to write this method however, we're going tohave to write our binary search like method first. In this case we'll call it getIndexNear.

``````
/*
works like a binary search
returns a location that is approximately where we want it
although it might be one less then where it actually starts
*/
private int getIndexNear (String name) {
int left = 0;   //lower index
int right = count-1; //upper index
int pivot = left + (right-left)/2;

while (right>=left) {
//finds the value to do the binary search
//comparisons on
int difference = names[pivot].compareTo(name);

//we have found the value equal to the value
//passed in, returns the location
if (difference == 0)
return pivot;

//case where new pivot is greater then value
//passed in
if (difference > 0) {
right = pivot-1; //updates upper index
}

//case where new pivot is less then value
//passed in
if (difference < 0) {
}

//updates pivot since one of the
//indexes have been updated
pivot = left + (right-left)/2;

}

return pivot; //returns the location
}
``````

Since we have finished that we can now go on to writing the filter method. Once the binary search like method is done writing the rest of this filter is a lot like writing the two previous filters.

``````
/*
Filter method
returns a SortedNames that only contains the elements
of the origonal list that were greater then the
input value

Uses binary search to improve its run time
*/
public Sortednames getGreaterThanBinary (string name){

//creates the new SortedNames, that the names that
//satisfy the filter will be added to
SortedNames bigNames = new SortedNames(names.length();

//uses the binary search like method to find the index
//about where the values that we want start
int goodStartingPlace = getIndexNear(name);

//iterates through the array adding the values to the new
//SortedNames, starting from the position that we just found
for(int index = goodStartingPlace; index < count; index++){

//current name satisfies the criteria
if(names[index].compareTo(name) > 0 {
bigName.insert(names[index]); //adds the name to the list
}
}
return bigNames;
}
``````