Unit 2 · 22 min
2.10 Implementing String Algorithms
Most string problems are a loop over substrings plus a test, a counter, or a string you build up.
Summary, objectives and course and exam description (CED) codes
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.
By the end of this session you can
- 2.10.A Develop code for standard and original algorithms that involve strings and determine the result of these algorithms.
Reviewed against the CED on
1LearnThe notes, the traps and how to remember them
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
trueas soon as you find one; returnfalseonly after the loop. - “Do all substrings have the property?” Return
falseas soon as one fails; returntrueonly 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)Lock it in: memory hooks
- One lettersubstring(i, i + 1): start at i, stop before i + 1, so you get exactly one character.
- Window of size kLast start index is length() - k, so loop while i <= length() - k.
- ReversePut each new letter in front: letter + result.
Common misconceptions
"word.substring(i, i + 1) == "a" checks whether the letter is an a."
Not quite. == compares references. substring creates a new String object, so == is false even when the letter matches. Use .equals("a").
"The last index of a string is length()."
Not quite. Indexes run from 0 to length() - 1. substring(i, i + 1) with i equal to length() throws a StringIndexOutOfBoundsException.
"Strings can be changed in place, one letter at a time."
Not quite. Strings are immutable. To reverse or edit a string, build a new string with concatenation and assign it to a variable.
Exam traps
- Comparing substrings with == compiles but gives false, so counts come out as 0.
- i <= str.length() in the loop condition throws a StringIndexOutOfBoundsException on the last pass.
- Comparing each letter with the next one: stop at length() - 1, not length().
- Returning false inside the loop on the first mismatch is correct only for an "every" check, never for an "any" check.
2PracticeRecall it, then check yourself
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.
Cover this list, say the points out loud, then take the checkpoint without scrolling back up.
Checkpoint · 5 questions
Checkpoint: Implementing String Algorithms
Pick an answer to mark it. Every answer is explained, and you can try any question again. Your saved score counts first tries only, and stays in this browser.
3PrevailLock it in for exam day
By the numbers
- Standard string algorithms three algorithms CED 2.10.A.1
- find if one or more substrings have a particular property
- determine the number of substrings that meet specific criteria
- create a new string with the characters reversed
Key terms: flip the cards
Read the term, say the definition out loud, then flip to check. Struggling a little to remember is what makes it stick.
-
String traversaltap to flip
Visiting the characters or substrings of a string one position at a time with a loop, usually with substring(i, i + 1).
Example and CED codes -
Stringtap to flip
A class whose objects hold a sequence of characters. String is a reference type in java.lang, and String objects are immutable.
Example and CED codes -
Indextap to flip
The position of a character in a String, counted from 0. Valid indices run from 0 to length() - 1.
Example and CED codes -
for looptap to flip
An iterative statement whose header has three parts: the initialization (runs once), the Boolean expression (checked before each iteration) and the update (after each iteration).
Example and CED codes -
Off by one errortap to flip
An error in which a loop runs one time too many or one time too few, often from < versus <= or a wrong starting value.
Example and CED codes -
Reference equality (== versus equals)tap to flip
Using == or != on object references checks whether they refer to the same object. A class's equals method checks whether two objects are equivalent.
Example and CED codes
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.