# AP® Computer Science A 2.10 Implementing String Algorithms

Source: https://lockincs.com/ap-csa/unit-2/2-10-implementing-string-algorithms/  
Last reviewed against the College Board Course and Exam Description (CED): 2026-11-12  
CED codes: 2.10.A, 2.10.A.1

Standard string algorithms traverse a string with a loop and substring. You should be able to find whether one or more substrings have a particular property, determine the number of substrings that meet specific criteria, and create a new string with the characters reversed. Compare substrings with equals, never ==, and keep loop bounds inside the string.

## What you will learn

- 2.10.A Develop code for standard and original algorithms that involve strings and determine the result of these algorithms.

## 1\. Traversing a string

String algorithms work by string traversal: a loop visits each position, and `substring` takes out the part to test. A single character at index `i` is `str.substring(i, i + 1)`. Indexes run from 0 to `length() - 1`.

```
String team = "Hawks";
for (int i = 0; i < team.length(); i++) {
    System.out.println(i + ": " + team.substring(i, i + 1));
}
```

Output:

```
0: H
1: a
2: w
3: k
4: s
```

**Watch out (off by one):** with `i <= team.length()`, the last pass asks for `substring(5, 6)` on a 5-letter string:

```
String team = "Hawks";
for (int i = 0; i <= team.length(); i++) {
    System.out.println(team.substring(i, i + 1));
}
```

Output:

```
H
a
w
k
s
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: Range [5, 6) out of bounds for length 5
```

The five letters print, then the program crashes on the sixth pass. (The exact wording of the message depends on the Java version.)

## 2\. Does a substring have a property?

There are standard string algorithms to find if one or more substrings have a particular property 2.10.A.1. Two kinds of question:

-   “Is there **any** substring with the property?” Return `true` as soon as you find one; return `false` only after the loop.
-   “Do **all** substrings have the property?” Return `false` as soon as one fails; return `true` only after the loop.

Does a word contain a double letter (the same letter twice in a row)? Each test compares the letter at `i` with the letter at `i + 1`, so the loop must stop before the last index.

```
public static boolean hasDoubleLetter(String word) {
    for (int i = 0; i < word.length() - 1; i++) {
        String here = word.substring(i, i + 1);
        String next = word.substring(i + 1, i + 2);
        if (here.equals(next)) {
            return true;
        }
    }
    return false;
}
```

```
System.out.println(hasDoubleLetter("balloon"));
System.out.println(hasDoubleLetter("planet"));
System.out.println(hasDoubleLetter(""));
```

Output:

```
true
false
false
```

**Watch out:** putting `else { return false; }` inside the loop would make the method stop after checking only the first pair, so `"balloon"` would return false.

Is every character a digit? `"0123456789".indexOf(ch)` is `-1` when `ch` is not a digit.

```
public static boolean allDigits(String code) {
    for (int i = 0; i < code.length(); i++) {
        String ch = code.substring(i, i + 1);
        if ("0123456789".indexOf(ch) == -1) {
            return false;
        }
    }
    return true;
}
```

```
System.out.println(allDigits("2026"));
System.out.println(allDigits("20x6"));
```

Output:

```
true
false
```

## 3\. Counting substrings that meet a criterion

There are standard string algorithms to determine the number of substrings that meet specific criteria 2.10.A.1. Count the vowels in a sentence:

```
String sentence = "Game over";
int vowels = 0;
for (int i = 0; i < sentence.length(); i++) {
    String ch = sentence.substring(i, i + 1);
    if ("aeiouAEIOU".indexOf(ch) >= 0) {
        vowels++;
    }
}
System.out.println("Vowels: " + vowels);
```

Output:

```
Vowels: 4
```

To count a pattern longer than one letter, use a window of that length. How many times does `"an"` appear in `"banana"`? The window `substring(i, i + 2)` needs `i + 2 <= length()`, so the loop condition is `i <= word.length() - 2`.

```
String word = "banana";
int count = 0;
for (int i = 0; i <= word.length() - 2; i++) {
    if (word.substring(i, i + 2).equals("an")) {
        count++;
    }
}
System.out.println(count);
```

Output:

```
2
```

| i | substring(i, i + 2) | equals “an”? | count |
| --- | --- | --- | --- |
| 0 | ba | no | 0 |
| 1 | an | yes | 1 |
| 2 | na | no | 1 |
| 3 | an | yes | 2 |
| 4 | na | no | 2 |

**Watch out (String comparison with ==):** this version compiles and runs, but `==` compares references, and every call to `substring` here returns a new String object.

```
String word = "banana";
int count = 0;
for (int i = 0; i < word.length(); i++) {
    if (word.substring(i, i + 1) == "a") {
        count++;
    }
}
System.out.println(count);
```

Output:

```
0
```

## 4\. Reversing a string

There are standard string algorithms to create a new string with the characters reversed 2.10.A.1. Strings are immutable, so you build a new string. Adding each character to the front reverses the order:

```
String word = "code";
String reversed = "";
for (int i = 0; i < word.length(); i++) {
    reversed = word.substring(i, i + 1) + reversed;
}
System.out.println(reversed);
```

Output:

```
edoc
```

| i | letter | reversed after this iteration |
| --- | --- | --- |
| 0 | c | c |
| 1 | o | oc |
| 2 | d | doc |
| 3 | e | edoc |

The other way: traverse from the last index down to 0 and add each character to the end. Start at `length() - 1`, not `length()`.

```
String word = "code";
String reversed = "";
for (int i = word.length() - 1; i >= 0; i--) {
    reversed += word.substring(i, i + 1);
}
System.out.println(reversed);
```

Output:

```
edoc
```

## 5\. Combining the algorithms

Original algorithms often combine the standard ones. A palindrome reads the same forward and backward: reverse the word, then compare with `equals`.

```
public static boolean isPalindrome(String word) {
    String reversed = "";
    for (int i = 0; i < word.length(); i++) {
        reversed = word.substring(i, i + 1) + reversed;
    }
    return reversed.equals(word);
}
```

```
System.out.println(isPalindrome("level"));
System.out.println(isPalindrome("lever"));
```

Output:

```
true
false
```

Another combination: remove every space from a string by building a new one that skips spaces.

```
String phrase = "a b  c";
String result = "";
for (int i = 0; i < phrase.length(); i++) {
    String ch = phrase.substring(i, i + 1);
    if (!ch.equals(" ")) {
        result += ch;
    }
}
System.out.println(result + " (" + result.length() + " letters)");
```

Output:

```
abc (3 letters)
```

## Common mix-ups

- Not true: word.substring(i, i + 1) == "a" checks whether the letter is an a. == compares references. substring creates a new String object, so == is false even when the letter matches. Use .equals("a").
- Not true: The last index of a string is length(). Indexes run from 0 to length() - 1. substring(i, i + 1) with i equal to length() throws a StringIndexOutOfBoundsException.
- Not true: Strings can be changed in place, one letter at a time. Strings are immutable. To reverse or edit a string, build a new string with concatenation and assign it to a variable.

## In 30 seconds

- Traverse a string with for (int i = 0; i < str.length(); i++) and str.substring(i, i + 1).
- To check every piece of length k, loop i from 0 while i <= str.length() - k and use substring(i, i + k).
- Property check: return or set a boolean as soon as one substring matches (or as soon as one fails).
- Counting: a counter starts at 0 before the loop; add 1 inside an if.
- Reverse: build a new string, adding each character to the front, or traverse from the last index down to 0.
- Compare strings with equals. == compares references.

## Checkpoint: 5 practice questions

### Question 1

Consider the following code segment. What is printed as a result of executing the code segment?

```java
String s = "aabbba";
int count = 0;
for (int i = 0; i < s.length() - 1; i++) {
    if (s.substring(i, i + 1).equals(s.substring(i + 1, i + 2))) {
        count++;
    }
}
System.out.println(count);
```

- A. 2
- B. 4
- C. 5
- D. 3

**Answer: D.** The loop compares each letter with the next one: aa (match), ab, bb (match), bb (match), ba. That is 3 matching pairs. Answering 2 counts the runs of repeated letters instead of the pairs; "bbb" contains two overlapping pairs.

### Question 2

Consider the following code segment. What is printed as a result of executing the code segment?

```java
String w = "stop";
String r = "";
for (int i = 0; i < w.length(); i += 2) {
    r = w.substring(i, i + 1) + r;
}
System.out.println(r);
```

- A. so
- B. os
- C. pots
- D. tp

**Answer: B.** The loop visits indexes 0 and 2 only, taking "s" and then "o". Each new letter is placed in front of r, so r becomes "s" and then "os". "so" adds letters to the end instead of the front, and "pots" reverses every letter, ignoring `i += 2`.

### Question 3

Consider the following code segment. What is printed as a result of executing the code segment?

```java
String word = "noon";
int n = 0;
for (int i = 0; i < word.length(); i++) {
    if (word.substring(i, i + 1) == "n") {
        n++;
    }
}
System.out.println(n);
```

- A. 2
- B. 4
- C. Nothing is printed because the code does not compile.
- D. 0

**Answer: D.** `==` compares object references, and each call to `substring` here creates a new String object, so the comparison is false every time and n stays 0. Answering 2 assumes `==` compares the characters, which `equals` does. Comparing two references with `==` is legal, so the code compiles.

### Question 4

The String `s` has been declared and initialized. A loop uses `s.substring(i, i + 3).equals("cat")` to count every place where "cat" appears in `s`. Which loop header checks every possible position without throwing an exception?

- A. `for (int i = 0; i <= s.length() - 3; i++)`
- B. `for (int i = 0; i < s.length(); i++)`
- C. `for (int i = 0; i < s.length() - 3; i++)`
- D. `for (int i = 0; i <= s.length() - 2; i++)`

**Answer: A.** A window of 3 characters starting at i needs `i + 3 <= s.length()`, so the last start index is `s.length() - 3`, and `<=` includes it. `i < s.length() - 3` skips the last possible position (an off by one error), so "cat" at the very end is missed. The other two headers go past the end and throw a `StringIndexOutOfBoundsException`.

### Question 5

The following method is intended to return `true` if its parameter contains at least one digit character, and `false` otherwise. For which of the following calls does the method NOT return the intended value?

```java
public static boolean hasDigit(String s) {
    for (int i = 0; i < s.length(); i++) {
        if ("0123456789".indexOf(s.substring(i, i + 1)) >= 0) {
            return true;
        } else {
            return false;
        }
    }
    return false;
}
```

- A. `hasDigit("7up")`
- B. `hasDigit("")`
- C. `hasDigit("room5")`
- D. `hasDigit("abcdef")`

**Answer: C.** The `else` returns false after checking only the first character, so the method decides from the first letter alone. For "room5" the first letter is not a digit and the method returns false, although the string contains 5. "7up" starts with a digit (true, correct); "" and "abcdef" correctly give false.

## Questions students ask

**How do you loop through a string in Java for the AP® exam?**

Use for (int i = 0; i < str.length(); i++) and get each character as a one-letter string with str.substring(i, i + 1). These methods are on the Java Quick Reference.

**How do you count occurrences of a letter in a string?**

Traverse the string, compare each one-letter substring with the target using equals, and add 1 to a counter when they match.

**How do you reverse a string in Java without library helpers?**

Start with an empty string and traverse the original. Add each character to the front of the result (result = letter + result), or loop from the last index down to 0 and add each character to the end.

**Why does my string loop throw StringIndexOutOfBoundsException?**

The loop goes one index too far. The last valid start index for substring(i, i + k) is length() - k, so the loop condition must stop there.

---

© LockInCS, licensed CC BY-NC-ND 4.0. AP® is a trademark registered by the College Board, which is not affiliated with, and does not endorse, this website.
