Opening the reading…
Opening the reading…
DSA FUNDAMENTALS › STRING BASICS
A substring takes characters from consecutive positions in the original string. For "abc", the valid non-empty substrings are "a", "ab", "abc", "b", "bc", and "c". The characters must stay next to each other in the original string, so "ac" is not a substring: it keeps the order but skips the character at index 1. This task considers only non-empty substrings, so the empty string is not included.
Does "ac" belong in the list of non-empty substrings of "abc"?
Checkpoints are not graded. They are here so you catch yourself before the quiz does — stuck, ask the tutor on the right.
Represent a substring by [start, end), where start is included and end is excluded. For "abc", start can be 0, 1, or 2. For each start, end begins at start + 1 and moves through n, which is 3. The end value 3 is valid even though the last character has index 2, because it marks the boundary immediately after the string.
| START | END VALUES | SUBSTRINGS |
|---|---|---|
| 0 | 1, 2, 3 | [0, 1) = "a", [0, 2) = "ab", [0, 3) = "abc" |
| 1 | 2, 3 | [1, 2) = "b", [1, 3) = "bc" |
| 2 | 3 | [2, 3) = "c" |
The outer choice fixes where a substring begins. The inner loop extends its exclusive end one position at a time, so it produces every possible length from that start. Each pair of boundaries identifies exactly one interval, and no pair is repeated. Because the inner loop starts at start + 1, it never creates an empty interval.
The boundary pair can stay the same in both languages, but the extraction method interprets its second argument differently. For the interval [1, 3), the substring is "bc". C++ string::substr takes the start and then the number of characters, so its second argument is 3 - 1, or 2. Java String.substring takes the start and then the exclusive end, so its second argument is 3.
string s = "abc";
for (int start = 0; start < n; start++) {
for (int end = start + 1; end <= n; end++) {
cout << s.substr(start, end - start) << endl;
}
}
// [1, 3) extracts "bc":
s.substr(1, 2);String s = "abc";
for (int start = 0; start < n; start++) {
for (int end = start + 1; end <= n; end++) {
System.out.println(s.substring(start, end));
}
}
// [1, 3) extracts "bc":
s.substring(1, 3);Fill in the missing Java exclusive-end argument so this extracts "bc" from "abc" starting at index 1.
s.substring(1, ___);Checkpoints are not graded. They are here so you catch yourself before the quiz does — stuck, ask the tutor on the right.
The number of intervals comes from the number of choices at each start. Start 0 creates 3 substrings, start 1 creates 2, and start 2 creates 1. Their total is 3 + 2 + 1 = 6, which matches n * (n + 1) / 2 when n is 3.
| SUBSTRING | LENGTH |
|---|---|
| "a" | 1 |
| "ab" | 2 |
| "abc" | 3 |
| "b" | 1 |
| "bc" | 2 |
| "c" | 1 |
Generating six intervals is one count of work, but extracting and printing them also handles the characters inside each interval. For "abc", the lengths are 1, 2, 3, 1, 2, and 1, which add up to 10 characters. In general, the number of intervals is O(n^2), while the total characters printed can be O(n^3), because long substrings are processed one character at a time.