The first free response question on the 2016 AP Computer Science exam, Random String Chooser, had you write a complete class that could be dropped into a bit of sample client code.
A quick note on this question, specifically building a class from scratch. The College Board has put a question where you either build an arbitrary class from scratch or build one that extends another class or implements an interface on most of the recent exams. It’s important that you know how to do this going into your AP exam.
Let’s look at the client code snippet that you’re given for part A.
String[] wordArray = {"wheels", "on", "the", "bus"};
RandomStringChooser sChooser = new RandomStringChooser(wordArray);
for (int k = 0; k < 6; k++) {
System.out.print(sChooser.getNext() + " ");
}
// Possible output
// bus the wheels on NONE NONE
What this tells you is that you need to create a constructor for the RandomStringChooser
class that takes an array of Strings and a method named getNext
that returns a string out of that set. The problem description goes into more detail and tells you that getNext
should return a random string from the array, without duplicating, and return "NONE"
if there are no more strings available.
The example output could be in any order as long as the two NONE
are at the end.
What they didn’t tell you, and not really important for the actual question, is you’re building something called an Iterator. If you take a computer science course after AP-A you’ll probably learn more about iterators.
Here’s a working solution. We’ll talk about it after you’ve had a chance to take a look.
import java.util.ArrayList;
public class RandomStringChooser {
private ArrayList<String> wordList;
public RandomStringChooser( String[] words ) {
wordList = new ArrayList<>();
for ( String word : words ) {
wordList.add( word );
}
}
public String getNext() {
if ( wordList.size() == 0 ) {
return "NONE";
}
int rnd = (int)(Math.random() * wordList.size());
return wordList.remove( rnd );
}
}
First line is an import because I wanted to use an ArrayList
to store the strings. You could have left this off. When grading, it’s assumed that anything you use has been imported correctly. But you would need this line to compile and run the code.
Next we come to the class signature public class RandomStringChooser
. This, along with correct method headers on the constructor and getNext
method, was worth a point.
You’re going to need an instance variable to store the words. I used an ArrayList
, but it could have been a standard array as well. It did need to be defined as private
for you to get this point.
The constructor needs to take an array of strings as a parameter and then initialize and fill your instance variable with those values. This was worth one point.
Your Random String Chooser class needs a getNext
method. This method is worth 4 points.
The first point is for generating a random number in the correct range to get a random string out of your list.
Using that random value to select a string from your instance variable was the second point. I used the remove
method instead of get
. They both return the value, but remove
also takes it out of the list.
The third point was for “updating state appropriately.” That is, you changed your instance variable so that the same string could not be returned again. In my case I killed two birds by using the remove
method of ArrayList
instead of get
.
And the last point was for returning "NONE"
when there weren’t any strings left to return.
Now that you’ve built the Random String Chooser class, it’s time to extend it.
Part B also gives you a snippet of client code. Let’s look at that first.
RandomLetterChooser letterChooser = new RandomLetterChooser("cat");
for (int k=0; k<4; k++) {
System.out.print(letterChooser.getNext());
}
// Possible output
// actNONE
This time instead of having an array of strings as the parameter, this constructor should take a normal string.
The code you’re given looks like this.
public class RandomLetterChooser extends RandomStringChooser {
public RandomLetterChooser(String str) {
// To be implemented in Part (B)
}
public static String[] getSingleLetters(String str) {
// Implementation not shown
}
}
Two things to notice here. First, you’re only worried about the constructor. You’re not writing a complete class this time. And second, there’s a method called getSingleLetters
that takes a string and returns it as a string array of letters. It shows Implementation not shown
. When they give you methods like that you should plan on calling them somewhere.
Here’s a working solution for part B.
public class RandomLetterChooser extends RandomStringChooser {
public RandomLetterChooser( String str ) {
super( getSingleLetters( str ) );
}
public static String[] getSingleLetters( String str ) {
String[] out = new String[str.length()];
for (int i=0; i<str.length(); i++) {
out[i] = str.substring(i, i+1);
}
return out;
}
}
You could get the two points for part b by filling in the constructor with the single line super( getSingleLetters( str ) );
. The rubric would give you one point for calling super(getSingleLetters(str));
on the first line. The second point comes from calling getSingleLetters(str)
somewhere in your solution.
Note that this solution also implements the getSingleLetters
method. That wasn’t part of this question, but I left it in as it’s a good method to solve when you’re preparing for the exam in May.