Random String Chooser FRQ Solution

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.

Part A – Random String Chooser Class

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.

getNext method

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.

Part B – Random Letter Chooser

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.

This site contains affiliate links. If you click an affiliate link and make a purchase we may get a small commission. It doesn't affect the price you pay, but it is something we must disclose.