FRQ 2021 Question 1:
(a) Write the WordMatch method scoreGuess. To determine the score to be returned, scoreGuess finds the number of times that guess occurs as a substring of secret and then multiplies that number by the square of the length of guess. Occurrences of guess may overlap within secret.
Assume that the length of guess is less than or equal to the length of secret and that guess is not an empty string. The following examples show declarations of a WordMatch object. The tables show the outcomes of some possible calls to the scoreGuess method.
(b) Write the WordMatch method findBetterGuess, which returns the better guess of its two String parameters, guess1 and guess2. If the scoreGuess method returns different values for guess1 and guess2, then the guess with the higher score is returned. If the scoreGuess method returns the same value for guess1 and guess2, then the alphabetically greater guess is returned.
Complete a ScoreGuess Method:
Collegeboard grading 9/9 Point Breakdown Part a:
- Compares guess to a substring of secret - 1/1
- Uses a substring of secret with correct length for comparison with guess - 1/1
- Loops through all necessary substrings of secret (no bounds errors) - 1/1
- Counts number of identified occurrences of guess within secret (in the context of a condition involving both secret and guess) - 1/1
- Calculates and returns correct final score - 1/1
Part b:
- Calls scoreGuess to get scores for guess1 and guess2 - 1/1
- Compares the scores - 1/1
- Determines which of guess1 and guess2 is alphabetically greater - 1/1
- Returns the identified guess1 or guess2 - 1/1
public class WordMatch {
private String secret;
public WordMatch(String word) {
secret = word;
}
public int scoreGuess(String guess) {
int guessLength = guess.length(); //Will be used to calculate score later
//Count occurrences of substring
int count = 0;
for (int i = 0; i < secret.length() - guessLength + 1; i++) {
if (secret.substring(i, i + guessLength).equals(guess)) {
count++;
}
}
return count * guessLength * guessLength; //Calculate and return score
}
public String findBetterGuess(String guess1, String guess2) {
String biggerGuess = "";
int score1 = scoreGuess(guess1); //calculate scores of the two guesses
int score2 = scoreGuess(guess2);
if (score1>score2) { //compare the scores
biggerGuess = guess1;
}
else if (score2>score1) {
biggerGuess = guess2;
}
else if (score1==score2) { // if the scores are the same, output the alphabetically higher guess
int biggerAlphabet = guess1.compareToIgnoreCase(guess2);
if (biggerAlphabet<0) {
biggerGuess = guess2;
}
else if (biggerAlphabet>0) {
biggerGuess = guess1;
}
}
return biggerGuess;
}
}
Testing:
public static void main(String[] args) {
System.out.println("Testing with mississippi:");
WordMatch wordMatch = new WordMatch("mississippi");
System.out.println(wordMatch.scoreGuess("i"));
System.out.println(wordMatch.scoreGuess("iss"));
System.out.println(wordMatch.scoreGuess("issipp"));
System.out.println(wordMatch.scoreGuess("mississippi"));
System.out.println("\nTesting with aaaabb:");
WordMatch wordMatch2 = new WordMatch("aaaabb");
System.out.println(wordMatch2.scoreGuess("a"));
System.out.println(wordMatch2.scoreGuess("aa"));
System.out.println(wordMatch2.scoreGuess("aaa"));
System.out.println(wordMatch2.scoreGuess("aabb"));
System.out.println(wordMatch2.scoreGuess("c"));
System.out.println("\nTesting with concatenation:");
WordMatch wordMatch3 = new WordMatch("concatenation");
System.out.println(wordMatch3.scoreGuess("ten"));
System.out.println(wordMatch3.scoreGuess("nation"));
System.out.println(wordMatch3.findBetterGuess("ten", "nation"));
System.out.println(wordMatch3.scoreGuess("con"));
System.out.println(wordMatch3.scoreGuess("cat"));
System.out.println(wordMatch3.findBetterGuess("con", "cat"));
}
main(null);
Testing with mississippi:
4
18
36
121
Testing with aaaabb:
4
12
18
16
0
Testing with concatenation:
9
36
nation
9
9
con
Java concepts to know:
- Methods
- Classes
- Strings
The Solution for #2
Below is the function I contructed for the FRQ
public class CombinedTable { // class representing two combined SingleTable objects
private SingleTable table1; // defining the two tables that will make up the CombinedTable object
private SingleTable table2;
public CombinedTable(SingleTable t1, SingleTable t2) { // constructor function for setting the variables
table1 = t1; // sets the table1 and table2 variables to their respective SingleTable objects
table2 = t2;
}
public boolean canSeat(int num) { // function
return num <= table1.getNumSeats()+table2.getNumSeats()-2;
}
public double getDesirability() {
double desirability = (table1.getViewQuality()+table2.getViewQuality())/2;
if (table1.getHeight()!=table2.getHeight()) {
desirability-=10;
}
return desirability;
}
}
Testing
I test the solution with a custom made SingleTable function
public class SingleTable {
private int numSeats; // instance variables shown
private int height;
private double viewQuality;
/** Constuctor sets up internal variables */
public SingleTable(int n, int h, double v) {
numSeats = n;
height = h;
viewQuality = v;
}
/**Returns the number of seats at this table. The value is always greater than or equal to 5 */
public int getNumSeats() {
/* implementation shown*/
return numSeats;
}
/** Returns the height of this table in centimeters. */
public int getHeight() {
/* implementation shown*/
return height;
}
/** Returns the quality of the view from this table. */
public double getViewQuality() {
/* implementation shown*/
return viewQuality;
}
/** Sets the quality of the view from this table to value*/
public void setViewQuality(double value) {
/* implementation shown*/
viewQuality = value;
}
}
public class CombinedTable { // class representing two combined SingleTable objects
private SingleTable table1; // defining the two tables that will make up the CombinedTable object
private SingleTable table2;
public CombinedTable(SingleTable t1, SingleTable t2) { // constructor function for setting the variables
table1 = t1; // sets the table1 and table2 variables to their respective SingleTable objects
table2 = t2;
}
public boolean canSeat(int num) { // function
return num <= table1.getNumSeats()+table2.getNumSeats()-2;
}
public double getDesirability() {
double desirability = (table1.getViewQuality()+table2.getViewQuality())/2;
if (table1.getHeight()!=table2.getHeight()) {
desirability-=10;
}
return desirability;
}
public static void main(String[] args) {
SingleTable t1 = new SingleTable(4,74,60.0);
SingleTable t2 = new SingleTable(8,74,70.0);
SingleTable t3 = new SingleTable(12,76,75.0);
CombinedTable c1 = new CombinedTable(t1, t2);
System.out.println(c1.canSeat(9));
System.out.println(c1.canSeat(11));
System.out.println(c1.getDesirability());
CombinedTable c2 = new CombinedTable(t2,t3);
System.out.println(c2.canSeat(18));
System.out.println(c2.getDesirability());
t2.setViewQuality(80);
System.out.println(c2.getDesirability());
}
}
CombinedTable.main(null);
true
false
65.0
true
62.5
67.5
AP Computer Science A Free-Response Question #3
SHOW ALL YOUR WORK. REMEMBER THAT PROGRAM SEGMENTS ARE TO BE WRITTEN IN JAVA. You may plan your answers in this orange booklet, but no credit will be given for anything written in this booklet. You will only earn credit for what you write in the separate Free Response booklet.
For this FRQ, I needed to create the key methods of a MemberInfo class, which contains an array list of ClubMembers. I wrote a add members and remove members methods.


public void addMembers(String[] names, int gradYear) {
// Iterate through the names array and add each member to memberList
for (String name : names) {
// Create a new ClubMember object with the provided name, gradYear, and good standing status
ClubMember newMember = new ClubMember(name, gradYear, true);
// Add the new member to the memberList
memberList.add(newMember);
}
}


In this code:
- We iterate through the names array, which contains the names of the new club members.
- For each name, we create a new ClubMember object with the provided name, gradYear, and set their initial standing status to true (assuming true represents “good standing”).
- We then add this new member to the memberList using the add method, assuming that memberList is some kind of collection or list (e.g., an ArrayList).
Make sure that you have the ClubMember class defined with appropriate attributes and constructor. The addMembers method assumes that you have an instance variable memberList to store the club members, and it adds new members to this list.
Here’s the removeMembers method that performs the described actions:
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
// Define the memberList variable
ArrayList<MemberInfo> memberList = new ArrayList<>();
public List<ClubMember> removeMembers(int year) {
// Create a list to store the graduated members in good standing
List<ClubMember> graduatedMembersInGoodStanding = new ArrayList<>();
// Create an iterator to traverse the memberList
Iterator<ClubMember> iterator = memberList.iterator();
while (iterator.hasNext()) {
ClubMember member = iterator.next();
if (member.getGradYear() <= year) {
// Check if the member has graduated
if (member.isInGoodStanding()) {
// Add the graduated member in good standing to the result list
graduatedMembersInGoodStanding.add(member);
}
// Remove the member from the memberList
iterator.remove();
}
}
// Return the list of graduated members in good standing
return graduatedMembersInGoodStanding;
}
In this code:
- We create a new ArrayList called graduatedMembersInGoodStanding to store the members who have graduated and are in good standing.
- We use an iterator to traverse the memberList and check each member’s graduation year and standing status.
- If a member has graduated (their graduation year is less than or equal to the provided year parameter), we check if they are in good standing (isInGoodStanding() method). If they are, we add them to the graduatedMembersInGoodStanding list.
- Regardless of their standing status, we remove the member from the memberList if they have graduated.
- Finally, we return the graduatedMembersInGoodStanding list, which contains the members who have graduated and are in good standing.

The removeMembers method in the ClubMembers class is designed to perform two main actions:
-
Identify Graduated Members in Good Standing: It first iterates through the list of club members (memberList) and identifies members who have graduated based on a provided year parameter. Additionally, it checks whether these members are in good standing.
-
Remove Graduated Members: After identifying graduated members, it removes them from the memberList, regardless of their standing status.
-
Return Graduated Members in Good Standing: Finally, the method returns a list containing members who have both graduated and are in good standing.
This method allows for efficient management of club membership by separating graduated members in good standing from the active member list while also maintaining a record of those members for further use or reporting.
Complete the removeMembers method as described:
public ArrayList<MemberInfo> removeMembers(int year)
Incomplete input:
| public ArrayList<MemberInfo> removeMembers(int year)
Assuming MemberInfo is a class that represents the information of a club member, here’s the completed method:
public ArrayList<ClubMember> removeMembers(int year) {
// Create a list to store the graduated members in good standing
ArrayList<ClubMember> graduatedMembersInGoodStanding = new ArrayList<>();
// Create an iterator to traverse the memberList
Iterator<ClubMember> iterator = memberList.iterator();
while (iterator.hasNext()) {
ClubMember member = iterator.next();
if (member.getGradYear() <= year) {
// Check if the member has graduated and is in good standing
if (member.isInGoodStanding()) {
// Add the graduated member in good standing to the result list
graduatedMembersInGoodStanding.add(member);
}
// Remove the member from the memberList
iterator.remove();
}
}
// Return the list of graduated members in good standing
return graduatedMembersInGoodStanding;
}
In this code, we assume that MemberInfo is a class that represents the information of a club member. The method performs the same actions as described in part (b):
-
It identifies members who have graduated based on the provided year parameter and checks if they are in good standing (isInGoodStanding() method).
-
If a member has graduated and is in good standing, they are added to the graduatedMembersInGoodStanding list.
-
Regardless of their standing status, members who have graduated are removed from the memberList using an iterator.
-
Finally, the method returns the graduatedMembersInGoodStanding list, which contains the members who have both graduated and are in good standing.
All the code put together
// This code builds the needed classes included in the FRQ
import java.util.ArrayList;
import java.util.Iterator;
public class ClubMember {
private int gradYear;
private boolean inGoodStanding;
public ClubMember(int gradYear, boolean inGoodStanding) {
this.gradYear = gradYear;
this.inGoodStanding = inGoodStanding;
}
public int getGradYear() {
return this.gradYear;
}
public boolean isInGoodStanding() {
return this.inGoodStanding;
}
}
public class MemberInfo {
private ArrayList<ClubMember> memberList;
public MemberInfo() {
memberList = new ArrayList<>();
}
//Part a starts here
public void addMembers(String[] names, int gradYear) {
// Iterate through the names array and add each member to memberList
for (String name : names) {
// Create a new ClubMember object with the provided name, gradYear, and good standing status
ClubMember newMember = new ClubMember(gradYear, true);
// Add the new member to the memberList
memberList.add(newMember);
}
}
public ArrayList<ClubMember> removeMembers(int year) {
// Create a list to store the graduated members in good standing
ArrayList<ClubMember> graduatedMembersInGoodStanding = new ArrayList<>();
// Create an iterator to traverse the memberList
Iterator<ClubMember> iterator = memberList.iterator();
while (iterator.hasNext()) {
ClubMember member = iterator.next();
if (member.getGradYear() <= year) {
// Check if the member has graduated and is in good standing
if (member.isInGoodStanding()) {
// Add the graduated member in good standing to the result list
graduatedMembersInGoodStanding.add(member);
}
// Remove the member from the memberList
iterator.remove();
}
}
// Return the list of graduated members in good standing
return graduatedMembersInGoodStanding;
}
}
Question #4
This question involves manipulating a two-dimensional array of integers. You will write two static methods of the ArrayResizer class, which is shown below.
public class ArrayResizer {
// /** Returns true if and only if every value in row r of array2D is non-zero. *
// * Precondition: r is a valid row index in array2D. *
// * Postcondition: array2D is unchanged. */
public static boolean isNonZeroRow(int[][] array2D, int r)
// { /* to be implemented in part (a) */ }
/** Returns the number of rows in array2D that contain all non-zero values.
* Postcondition: array2D is unchanged.
*/
public static int numNonZeroRows(int[][] array2D)
{ /* implementation not shown */ }
/** Returns a new, possibly smaller, two-dimensional array that contains only rows
* * from array2D with no zeros, as described in part (b).
* * Precondition: array2D contains at least one column and at least one row with no zeros.
* * Postcondition: array2D is unchanged. */
public static int[][] resize(int[][] array2D)
{ /* to be implemented in part (b) */ }
}
| public static boolean isNonZeroRow(int[][] array2D, int r)
';' expected
Number 4 Question A
A) Write the method isNonZeroRow, which returns true if and only if all elements in row r of a two-dimensional array array2D are not equal to zero.
- For example, consider the following statement, which initializes a two-dimensional array
- Answer to question A:
public static boolean isNonZeroRow(int[][] array2D, int r) {
// Iterate through the elements in row r
for (int i = 0; i < array2D[r].length; i++) {
if (array2D[r][i] == 0) {
// If any element is equal to zero, return false immediately
return false;
}
}
// If the loop completes without finding any zero element, return true
return true;
}
The isNonZeroRow method, when given a two-dimensional array array2D and a row index r, performs the following tasks:
- It iterates through the elements in the specified row.
- For each element in the row, it checks whether it is equal to zero.
- If any element in the row is found to be zero during the iteration, the method immediately returns false, indicating that at least one zero is present in the row.
- If the loop completes without finding any zero element, the method returns true, signifying that all elements in the row are non-zero.
- This method adheres to the precondition that r is a valid row index and ensures the postcondition that the array2D remains unchanged after the operation.
Question B
Write the method resize, which returns a new two-dimensional array containing only rows from array2D with all non-zero values. The elements in the new array should appear in the same order as the order in which they appeared in the original array
import java.util.Arrays;
public class ArrayResizer {
// Helper method to check if a row contains all non-zero values
public static boolean isNonZeroRow(int[][] array2D, int r) {
for (int i = 0; i < array2D[r].length; i++) {
if (array2D[r][i] == 0) {
return false;
}
}
return true;
}
// Helper method to count the number of rows with all non-zero values
public static int numNonZeroRows(int[][] array2D) {
int count = 0;
for (int i = 0; i < array2D.length; i++) {
if (isNonZeroRow(array2D, i)) {
count++;
}
}
return count;
}
// Returns a new array containing only rows with all non-zero values
public static int[][] resize(int[][] array2D) {
int numNonZeroRows = numNonZeroRows(array2D);
int[][] result = new int[numNonZeroRows][];
int resultIndex = 0;
for (int i = 0; i < array2D.length; i++) {
if (isNonZeroRow(array2D, i)) {
result[resultIndex] = Arrays.copyOf(array2D[i], array2D[i].length);
resultIndex++;
}
}
return result;
}
public static void main(String[] args) {
int[][] arr = {
{2, 1, 0},
{1, 3, 2},
{0, 0, 0},
{4, 5, 6}
};
int[][] smaller = resize(arr);
// Print the contents of the 'smaller' array
for (int[] row : smaller) {
System.out.println(Arrays.toString(row));
}
}
}
The ArrayResizer class contains several methods for working with two-dimensional arrays in Java:
- The
isNonZeroRowmethod checks if all elements in a specified row are non-zero and returns true if they are, or false if there is at least one zero. - The
numNonZeroRowsmethod counts the number of rows in a two-dimensional array that contain all non-zero values. - The
resizemethod creates a new array, smaller in size, containing only the rows from the original array with all non-zero values. It ensures the elements appear in the same order as in the original array.
A main method demonstrates the usage of the resize method by initializing a sample two-dimensional array arr, calling resize to create a new array smaller, and then printing the contents of smaller. This class provides functionality for handling and resizing arrays based on non-zero values efficiently.
For scoreGuess Method:
- Method Purpose: Calculates the score of a guessed word based on its occurrences in the secret word.
- Method Signature:
public int scoreGuess(String guess) - Input Parameters:
guess: The guessed word to calculate the score for.
- Output: Returns the score of the guessed word.
- Precondition: The
guessmust be a valid string. - Postcondition: The
secretremains unchanged after calling this method.
For findBetterGuess Method:
- Method Purpose: Compares two guessed words and returns the one with a higher score. If the scores are equal, it returns the alphabetically higher guess.
- Method Signature:
public String findBetterGuess(String guess1, String guess2) - Input Parameters:
guess1: The first guessed word to compare.guess2: The second guessed word to compare.
- Output: Returns the better guess based on the scoring and alphabetical order.
- Precondition: Both
guess1andguess2must be valid strings. - Postcondition: The
secretremains unchanged after calling this method.
Usage Example:
- You can call these methods from within the
WordMatchclass. - To demonstrate usage, consider initializing a secret word, like
secret, and using thescoreGuessmethod to calculate the score of a guess, likeguess. These key points should help you understand and use the methods effectively.For
isNonZeroRowMethod:
For ClubMember Class:
- Class Purpose: Represents a club member with their graduation year and membership status.
- Constructor Signature:
public ClubMember(int gradYear, boolean inGoodStanding) - Input Parameters:
gradYear: The graduation year of the club member.inGoodStanding: The membership status of the club member.
- Methods:
getGradYear(): Returns the graduation year of the club member.isInGoodStanding(): Returns the membership status of the club member.
For MemberInfo Class:
- Class Purpose: Manages a list of club members and provides methods to add and remove members.
- Constructor Signature:
public MemberInfo() - Methods:
- For
addMembersMethod:- Method Purpose: Adds new members to the club.
- Method Signature:
public void addMembers(String[] names, int gradYear) - Input Parameters:
names: The names of the new members to be added.gradYear: The graduation year of the new members.
- Output: None. This method adds new members to the club’s member list.
- Precondition: The
namesarray must not be null and must contain at least one name. ThegradYearmust be a valid year. - Postcondition: The new members are added to the club’s member list.
- For
removeMembersMethod:- Method Purpose: Removes members who have graduated from the club.
- Method Signature:
public ArrayList<ClubMember> removeMembers(int year) - Input Parameters:
year: The current year. Members who have graduated by this year are removed from the club.
- Output: Returns a list of members who have graduated and were in good standing at the time of removal.
- Precondition: The
yearmust be a valid year. - Postcondition: Members who have graduated by the given year are removed from the club’s member list. A list of removed members who were in good standing is returned.
- For
- Method Purpose: Determines if all elements in a specified row of a 2D array are non-zero.
- Method Signature:
public static boolean isNonZeroRow(int[][] array2D, int r) - Input Parameters:
array2D: The 2D array to examine.r: The row index to check for non-zero values.
- Output: Returns
trueif all elements in the row are non-zero, otherwise returnsfalse. - Precondition: The row index
rmust be valid for the givenarray2D. - Postcondition: The
array2Dremains unchanged after calling this method.
For numNonZeroRows Method:
- Method Purpose: Counts the number of rows in a 2D array that contain only non-zero values.
- Method Signature:
public static int numNonZeroRows(int[][] array2D) - Input Parameter:
array2D: The 2D array to count non-zero rows in. - Output: Returns the count of rows with all non-zero values.
- Precondition: None specified.
- Postcondition: The
array2Dremains unchanged after calling this method.
For resize Method:
- Method Purpose: Creates a new 2D array containing only rows from the original array with all non-zero values.
- Method Signature:
public static int[][] resize(int[][] array2D) - Input Parameter:
array2D: The original 2D array. - Output: Returns a new 2D array with non-zero rows from the original array.
- Precondition: The
array2Dmust contain at least one column and at least one row with no zeros. - Postcondition: The
array2Dremains unchanged after calling this method.
Usage Example:
- You can call these methods from within the
ArrayResizerclass. - To demonstrate usage, consider initializing a 2D array, like
arr, and using theresizemethod to create a smaller array, likesmaller.
These key points should help you understand and use the methods effectively.