Algorithms with Selection and Repetition
Introduces the three building blocks of algorithms: sequencing, selection, and repetition. You represent algorithms in plain language or diagrams before coding them in Java.
Unit 2 teaches you how to make programs choose between paths using Boolean expressions and if statements, and how to repeat code using while and for loops. You also learn standard algorithms, string processing, nested loops, and how to count how many times statements execute.
Fiveable's AP Computer Science A Unit 2 review covers 13 topics, with guided practice questions for the unit.
Introduces the three building blocks of algorithms: sequencing, selection, and repetition. You represent algorithms in plain language or diagrams before coding them in Java.
Covers relational operators ==, !=, <, >, <=, >= and the rule that primitive comparisons check values while reference comparisons check memory addresses.
Introduces one-way (if) and two-way (if-else) selection. The body of an if runs only when its Boolean expression is true; the else body runs when it is false.
Covers nested if statements and multiway if-else-if chains. The inner condition is only evaluated when the outer condition is true; the first true branch in a chain runs and the rest are skipped.
Introduces !, &&, and || with precedence order ! then && then ||. Short-circuit evaluation means the second operand may not be evaluated.
Covers Boolean equivalence, truth tables, De Morgan's law, and comparing object references with == and != including null checks and .equals().
A while loop checks its condition before every iteration. It can run zero times, and it causes an infinite loop if the condition never becomes false. Off-by-one errors are common.
A for loop header contains initialization, Boolean condition, and update. Initialization runs once; the condition is checked before each iteration; the update runs after each body execution.
Standard algorithms using loops and conditionals: divisibility with %, digit extraction with % and /, frequency counting, min/max tracking, and sum/average with accumulators.
String algorithms use charAt, substring, length, and indexOf inside loops to check substring properties, count matches, and build reversed strings.
The inner loop completes all its iterations each time the outer loop advances once. Total execution count is the product of bounds for independent loops or triangular for dependent bounds.
Count how many times a statement executes by tracing loop bounds. Single loops are linear; independent nested loops are quadratic; triangular nested loops produce n(n-1)/2 executions.
Review AP Computer Science A Topic 2.6, including equivalent Boolean expressions, comparing Boolean expressions, truth tables, De Morgan's law, !(a && b), !(a || b), ==, !=, null checks, and .equals().
Try AP-style questions on unit 2, then use the review notes below for anything you miss.
A timed, AP-style test built only from unit 2 questions — multiple choice plus free response, scored with AI feedback. Use the standard format or build your own.
An algorithm is a step-by-step process for solving a problem. The three building blocks are sequencing (executing statements in order), selection (branching based on a true or false condition), and repetition (looping until a goal is reached). You can represent algorithms in plain language or with flowcharts before writing Java code. The order in which these building blocks appear changes the outcome.
Describe a real-world task, such as sorting mail, using all three building blocks. Identify where the selection and repetition occur.
| Building block | Java construct | When to use |
|---|---|---|
| Sequencing | Statements in order | Steps that must happen in a fixed sequence |
| Selection | if, if-else, if-else-if | Different actions needed for different conditions |
| Repetition | while, for | Same action needed multiple times until a goal is met |
A Boolean expression evaluates to either true or false. Relational operators compare two values and produce a Boolean result. With primitive types, == and != compare actual values. With reference types, == and != compare object references, not content. To compare String content, use .equals().
Write a Boolean expression that is true when an int variable score is between 70 and 89 inclusive. Then explain why you cannot use == to compare two String variables for equal content.
| Operand type | Operator | What is compared |
|---|---|---|
| int, double, char | ==, !=, <, >, <=, >= | Actual primitive values |
| Object references | ==, != | Memory addresses (same object?) |
| String content | .equals() | Character-by-character content |
An if statement changes sequential flow by running a block only when its Boolean expression is true. An if-else adds a second block for when the condition is false. Nested if statements place one decision inside another; the inner condition is only evaluated when the outer condition is true. A multiway if-else-if chain checks conditions in order and executes the first true branch, then skips all remaining branches. If no condition is true and a trailing else exists, that else block runs.
Trace this logic: a variable grade is 85. An if-else-if checks grade >= 90 first, then grade >= 80, then grade >= 70, with a trailing else. Which block runs and why?
| Form | Blocks that can run | When to use |
|---|---|---|
| if | 0 or 1 | Optional action under one condition |
| if-else | Exactly 1 of 2 | Two mutually exclusive outcomes |
| if-else-if | 0 or 1 of many | Multiple mutually exclusive categories |
| Nested if | Depends on outer | Layered conditions where inner depends on outer |
Logical operators combine Boolean expressions. ! (not) negates a value. && (and) is true only when both operands are true. || (or) is true when at least one operand is true. Precedence order is !, then &&, then ||. Short-circuit evaluation means Java stops evaluating as soon as the result is determined: for &&, if the left side is false, the right side is skipped; for ||, if the left side is true, the right side is skipped. Two Boolean expressions are equivalent if they produce the same result for every possible input. De Morgan's law gives two key equivalences: !(a && b) equals !a || !b, and !(a || b) equals !a && !b. Truth tables prove equivalence by listing all input combinations.
Apply De Morgan's law to rewrite !(x > 5 && y < 10) without the outer negation. Then build a truth table for a && !b to verify your understanding.
| Operator | True when | Short-circuits when |
|---|---|---|
| ! | Operand is false | Always (single operand) |
| && | Both operands are true | Left operand is false |
| || | At least one operand is true | Left operand is true |
A while loop evaluates its Boolean condition before every iteration, including the first. If the condition is false initially, the loop body never runs. The loop continues as long as the condition is true. If the condition never becomes false, the result is an infinite loop. Off-by-one errors occur when the loop runs one time too many or too few, usually because the condition uses < instead of <= or vice versa. A loop control variable must be initialized before the loop and updated inside the loop body.
Write a while loop that sums integers from 1 to 10. Identify the initialization, condition, body, and update. Then change the condition to cause an off-by-one error and explain what goes wrong.
A for loop header has three parts: initialization (runs once before the first condition check), Boolean expression (checked before every iteration), and update (runs after every loop body execution). The variable declared in the initialization is the loop control variable. A for loop can always be rewritten as an equivalent while loop and vice versa. For loops are preferred when the number of iterations is known in advance.
Trace a for loop with header for(int i = 1; i <= 5; i++) that prints i * i. List the value of i and the output for each iteration. Then rewrite it as an equivalent while loop.
| Loop type | Condition checked | Best use case |
|---|---|---|
| while | Before each iteration (pretest) | Unknown number of iterations; event-driven termination |
| for | Before each iteration (pretest) | Known number of iterations; index-based traversal |
Standard algorithms combine if statements and loops to solve common problems without using arrays. The modulus operator % finds remainders and tests divisibility. Digit extraction uses % 10 to get the last digit and integer division by 10 to remove it, repeating in a loop. Frequency counting uses a conditional increment inside a loop. Min and max tracking initializes a variable to the first value and updates it when a new value is smaller or larger. Sum and average use an accumulator variable updated each iteration.
Write a loop that counts how many digits in a positive integer are greater than 5. Identify which standard algorithm patterns you are combining.
| Algorithm | Key operation | Pattern |
|---|---|---|
| Divisibility check | n % d == 0 | Single Boolean expression |
| Digit extraction | n % 10, n / 10 | while loop, shrink n each pass |
| Frequency count | if condition, count++ | Accumulator with conditional increment |
| Min/max tracking | if new > max, update | Accumulator with conditional update |
| Sum and average | sum += value | Accumulator, divide by count at end |
String algorithms use loops with String methods to examine text one character or substring at a time. The three standard goals are checking whether substrings have a property, counting substrings that meet criteria, and building a reversed string. Key methods are charAt(i) to get a character at index i, substring(start, end) to extract a portion, length() to get the string length, and indexOf() to search. Loop bounds matter: valid indices run from 0 to length() - 1. Strings are immutable, so building a new string requires concatenation or a new variable.
Write a loop that builds the reverse of a String s by concatenating characters from the last index to index 0. Identify the loop bounds and explain why length() - 1 is the correct starting index.
Nested iteration places one loop inside another. The inner loop completes all of its iterations every time the outer loop runs once. To trace nested loops, track both loop variables together. The total number of inner loop body executions is the product of the outer and inner iteration counts for independent bounds. When inner bounds depend on the outer variable, the count is triangular.
Trace a nested loop where the outer runs i from 0 to 2 and the inner runs j from 0 to i. List every (i, j) pair that executes and count the total inner loop body executions.
| Loop structure | Total inner executions | Example |
|---|---|---|
| Independent bounds (m outer, n inner) | m * n | for i 0..2, for j 0..3: 12 executions |
| Dependent bounds (inner 0 to i) | n(n-1)/2 | for i 0..4, for j 0..i: 10 executions |
A statement execution count is the number of times a specific statement runs. You find it by tracing the loop structure and counting iterations. For a single loop running n times, a statement in the body executes n times. For independent nested loops with bounds m and n, the inner body executes m * n times. For a triangular nested loop, the inner body executes approximately n squared divided by 2 times. Informal run-time analysis compares two iterative segments by comparing their execution counts as input size grows, without requiring formal Big O notation.
Given a nested loop where the outer runs from 1 to 4 and the inner runs from 1 to 3, calculate the exact execution count of a statement in the inner body. Then describe how the count changes if both bounds double.
| Loop structure | Execution count formula | Growth type |
|---|---|---|
| Single loop, bound n | n | Linear |
| Independent nested loops, bound n each | n * n | Quadratic |
| Triangular nested loop, bound n | n(n-1)/2 | Quadratic (slower constant) |
| Term | Definition |
|---|---|
| relational operator | An operator that compares two values and returns a Boolean result. In AP CSA the relational operators are ==, !=, <, >, <=, and >=. |
| == (equality operator) | Compares two values for equality. With primitives it compares actual values; with reference types it compares object references, not content. |
| short-circuit evaluation | Java stops evaluating && when the left operand is false, and stops evaluating || when the left operand is true, so the right operand may never be checked. |
| De Morgan's law | !(a && b) is equivalent to !a || !b, and !(a || b) is equivalent to !a && !b. Use these rules to rewrite negated compound conditions. |
| truth tables | A table listing all true/false input combinations and their output for a Boolean expression, used to prove two expressions are equivalent. |
| off by one error | A loop runs one iteration too many or too few because the condition uses < instead of <= or the counter is initialized incorrectly. |
| accumulator pattern | A variable is initialized before a loop and updated inside the loop body each iteration to compute a running sum, count, or other aggregate. |
| accumulator variable | The variable used in the accumulator pattern; initialized once and incremented or updated repeatedly during iteration. |
| digit extraction | A standard algorithm that uses n % 10 to get the ones digit and n / 10 to remove it, repeated in a while loop until n equals 0. |
| maximum value algorithm | Initialize a max variable to the first value, then compare each subsequent value inside a loop and update max when a larger value is found. |
| object reference | A variable that holds a memory address pointing to an object. Using == on two reference variables checks whether they point to the same object. |
| null comparison | Use obj == null or obj != null to check whether a reference variable holds an object before calling methods on it. |
| count variable | A variable incremented inside a loop only when a condition is true, used to count how many values meet a specific criterion. |
== on two String variables checks whether they reference the same object, not whether they contain the same characters. Use .equals() to compare String content. This mistake causes code to behave correctly sometimes (when the JVM reuses the same literal) and fail other times.
Using < n when you need <= n, or starting at 1 instead of 0, causes the loop to run one iteration too few or too many. For String traversal, valid indices are 0 through length() - 1, so a loop condition of i < s.length() is correct; i <= s.length() causes an IndexOutOfBoundsException.
If the variable that controls the while condition is never changed inside the loop body, the condition stays true forever and the loop never terminates. Always check that the loop body moves the control variable toward the termination condition.
A common error is distributing the negation without flipping the operator: !(a && b) is NOT !a && !b. The correct form is !a || !b. Write out a small truth table to verify any De Morgan's transformation before trusting it.
In a nested for loop, the inner loop control variable is re-initialized every time the outer loop advances. Students sometimes trace as if the inner variable continues from where it left off, which produces incorrect output and execution counts.
Multiple-choice questions frequently give a code segment with if statements, while loops, for loops, or nested loops and ask what value a variable holds or what the code prints. Practice tracing every statement in order, tracking variable values at each step, and applying short-circuit evaluation rules to compound conditions.
Free-response questions ask you to write methods that use selection and iteration to implement a described algorithm. Common tasks include counting values that meet a condition, finding a minimum or maximum, processing characters in a String, and combining loops with if statements. Identify the algorithm pattern first, then write the loop structure and condition.
Multiple-choice questions present two Boolean expressions and ask whether they are equivalent, or give a condition and ask which rewritten form produces the same result. Apply De Morgan's law, check operator precedence, and use a small truth table with two or three test cases to verify equivalence quickly.

Unit 2 printables
Print the unit cheatsheets ($3) or unit exams ($5) for Unit 2. Yours to keep, no subscription needed.
get printablesThe AP CSA Unit 2 progress check in AP Classroom includes both MCQ and FRQ parts drawn from the unit's 12 topics. The MCQ portion tests Boolean expressions, `if` and nested `if` statements, compound conditions, `while` loops, `for` loops, and informal run-time analysis. The FRQ portion asks you to write or trace code using selection and iteration, including string algorithms and nested loops. Working through the progress check is one of the best ways to find gaps before the real exam. You can find matched practice at AP CSA Unit 2.
AP CSA Unit 2 FRQs typically ask you to write methods that use `if` statements, `while` loops, `for` loops, or nested iteration to solve a problem, and string algorithm questions are common too. To practice, write out full method bodies by hand, trace through your logic step by step, and check edge cases like empty strings or loop boundaries. Focus especially on topics 2.9 (Implementing Selection and Iteration Algorithms) and 2.10 (Implementing String Algorithms), since those map most directly to free-response writing. Find practice problems at AP CSA Unit 2.
Start with Boolean expressions (topic 2.2) and `if` statements (2.3-2.5) before moving to loops, since selection logic is the foundation for everything else in this unit. Once conditions click, work through `while` loops (2.7) and `for` loops (2.8) separately, then practice nested iteration (2.11) and string algorithms (2.10) together since they combine both skills. Here's a concrete plan:
- Trace existing code by hand before writing your own, especially for nested loops.
- Write small methods from scratch for topics 2.9 and 2.10, then test edge cases.
- Use informal run-time analysis (2.12) to check whether your loops are efficient.
- Do a timed set of MCQs to catch tricky compound Boolean expression questions. Since this unit is 25-35% of the exam, it's worth revisiting it more than once. AP CSA Unit 2 has resources organized by topic to help you target weak spots.
int runs = 0;
int n = /* missing initialization */;
for (int i = 1; i < n; i *= 2) {
for (int j = 0; j < i; j++) {
runs++;
}
}String str1 = /* missing initialization */;
String str2 = /* missing initialization */;
boolean diff = (str1 != str2) == str1.equals(str2);public class DirectionDisplay
{
/** Consumes and returns the next command, which is exactly "L", "R" or "S".
* There are enough commands for every requested call. */
public String readToken() { /* implementation not shown */ }
/** Implements the behavior and preconditions in part (a). */
public int finalDirection(int moves)
{ /* to be implemented in part (a) */ }
/** Implements the behavior and preconditions in part (b). */
public String rotateLabel(String label, int positions)
{ /* to be implemented in part (b) */ }
}