Lecture 10 Nested Loops

Joseph Haugh

University of New Mexico

Loop Refresher

  • Recall, the syntax of the while loop:

    while (<<booleanCondition>>) {
        <<<bodyStatements>>>
    }
  • As well as the syntax of the for loop:

    for (<<initStatement>>; <<booleanCondition>>; <<updateStatement>>) {
        <<bodyStatements>>
    }
  • What statements are allowed in <<bodyStatements>>?

  • Any valid statements!

  • This includes loops!

Nested Loops

  • Nested loops can be intimidating at first

  • However, they follow the same rules as any other loop

  • For example, let’s step through the following code:

    void main() {
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                IO.println("(" + i + ", " + j + ")");
            }
        }
    }
  • Copy and paste this code into Intellij and set a breakpoint on the first loop

  • What does it print?

Nested Loops

Code

void main() {
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            IO.println("(" + i + ", " + j + ")");
        }
    }
}

Output

(0, 0)
(0, 1)
(0, 2)
(1, 0)
(1, 1)
(1, 2)
(2, 0)
(2, 1)
(2, 2)

Nested Loops

Code

void main() {
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            IO.println("(" + i + ", " + j + ")");
        }
    }
}

Pseudocode

  • For every i in range [0, 3)
    • For every j in range [0, 3)
      • Print: (i, j)

Output

(0, 0)
(0, 1)
(0, 2)
(1, 0)
(1, 1)
(1, 2)
(2, 0)
(2, 1)
(2, 2)

Dependent Nested Loop

  • The nested loop can see changes to variables declared in the outer loop

  • For example, we could start the nested loops j variable at i’s value

  • What does this code print?

    void main() {
        for (int i = 0; i < 3; i++) {
            for (int j = i; j < 3; j++) {
                IO.println("(" + i + ", " + j + ")");
            }
        }
    }

Dependent Nested Loop

Code

void main() {
    for (int i = 0; i < 3; i++) {
        for (int j = i; j < 3; j++) {
            IO.println("(" + i + ", " + j + ")");
        }
    }
}

Pseudocode

  • For every i in range [0, 3)
    • For every j in range [i, 3)
      • Print: (i, j)

Output

(0, 0)
(0, 1)
(0, 2)
(1, 1)
(1, 2)
(2, 2)

Example: PlusOut

  • Let’s write a function together called plusOut
  • plusOut is given a String, s, and another String, word
  • It must then return a new String where all characters have been replaced with +
  • Except for appearances of the word parameter
  • For example:
plusOut("12xy34", "xy") -> "++xy++"
plusOut("12xy34", "1") -> "1+++++"
plusOut("12xy34xyabcxy", "xy") -> "++xy++xy+++xy"
  • Key phrases:
    • New string
    • All characters replaced with +
    • Except for appearances of the word parameter

Example: PlusOut

  • Disclaimer: this function will get long and relatively complicated. I show it as an example of the thought process and trial and error which come with coding.
  • Note: I will put line numbers next to relevant bullet points which reference the code in parens (line number)

Example: PlusOut

  • To get started let’s write out our function with comments identifying the key aspects
String plusOut(String s, String word) {
    // Create a new string to return
    // All characters in s replaced with +
    // Except for appearances of word
}

Example: PlusOut

  • Now let’s add code for the easy lines which in this case is creating a result String (3)
  • As well as returning it (6)
String plusOut(String s, String word) {
    // Create a new string to return
    String result = "";
    // All characters in s replaced with +
    // Except for appearances of word
    return result;
}

Example: PlusOut

  • We still have low hanging fruit
  • Since the problem specifies all characters in s are affected we know we need to loop over s (5-7)
String plusOut(String s, String word) {
    // Create a new string to return
    String result = "";
    // All characters in s replaced with +
    for (int i = 0; i < s.length(); i++) {
        // Except for appearances of word 
    }
    return result;
}

Example: PlusOut

  • Do we only want to access the single character at index i?
  • No, instead we want the next n characters where n is the length of word
  • We also need a place to store these n characters as we get them, so we need another String (6)
  • How do we retrieve these n characters?
  • Another loop! (7-9)
String plusOut(String s, String word) {
    // Create a new string to return
    String result = "";
    // All characters in s replaced with +
    for (int i = 0; i < s.length(); i++) {
        String nextN = "";
        for (int j = i; j < word.length(); j++) {
            nextN += s.charAt(j);
        }
        // Except for appearances of word
    }
    return result;
}

Example: PlusOut

  • Reading the code
  • Store the answer in result (3)
  • For every index in s (5-11)
    • Store the next n characters in nextN(6)
    • For n iterations, where n is the length of word(7-9)
      • Append the character to nextN(8)
String plusOut(String s, String word) {
    // Create a new string to return
    String result = "";
    // All characters in s replaced with +
    for (int i = 0; i < s.length(); i++) {
        String nextN = "";
        for (int j = i; j < word.length(); j++) {
            nextN += s.charAt(j);
        }
        // Except for appearances of word
    }
    return result;
}

Example: PlusOut

  • Now we need to determine if the nextN is equal to word (11)

  • If it is we need to append word to the result (12)

  • Otherwise, we need to append a + (14)

  • Does this work?

  • Try this:

    plusOut("1xy2", "xy");
String plusOut(String s, String word) {
    // Create a new string to return
    String result = "";
    // All characters in s replaced with +
    for (int i = 0; i < s.length(); i++) {
        String nextN = "";
        for (int j = i; j < word.length(); j++) {
            nextN += s.charAt(j);
        }
        // Except for appearances of word
        if (nextN.equals(word)) {
            result += nextN;
        } else {
            result += '+';
        }
    }
    return result;
}

Example: PlusOut

plusOut("1xy2", "xy");
  • Results in all +!
  • What went wrong?
  • Our nested loop is incorrect!
  • It needs to loop up to word.length() + i (7)
String plusOut(String s, String word) {
    // Create a new string to return
    String result = "";
    // All characters in s replaced with +
    for (int i = 0; i < s.length(); i++) {
        String nextN = "";
        for (int j = i; j < word.length() + i; j++) {
            nextN += s.charAt(j);
        }
        // Except for appearances of word
        if (nextN.equals(word)) {
            result += nextN;
        } else {
            result += '+';
        }
    }
    return result;
}

Example: PlusOut

plusOut("1xy2", "xy");
  • It right now?
  • No, now we get an index out of bounds error, why?
  • We perform the nested loop for every index in s including the last
  • We need to guard against this case (7)
String plusOut(String s, String word) {
    // Create a new string to return
    String result = "";
    // All characters in s replaced with +
    for (int i = 0; i < s.length(); i++) {
        String nextN = "";
        if (word.length() + i <= s.length()) {
            for (int j = i; j < word.length() + i; j++) {
                nextN += s.charAt(j);
            }
        }
        // Except for appearances of word
        if (nextN.equals(word)) {
            result += nextN;
        } else {
            result += '+';
        }
    }
    return result;
}

Example: PlusOut

plusOut("1xy2", "xy");
  • Please let it be right!
  • Not quite
  • We include an extra character
  • Can you see why?
  • We need to increment i by the number of iterations we took in nested loop when we find word
String plusOut(String s, String word) {
    // Create a new string to return
    String result = "";
    // All characters in s replaced with +
    for (int i = 0; i < s.length(); i++) {
        String nextN = "";
        if (word.length() + i <= s.length()) {
            for (int j = i; j < word.length() + i; j++) {
                nextN += s.charAt(j);
            }
        }
        // Except for appearances of word
        if (nextN.equals(word)) {
            result += nextN;
        } else {
            result += '+';
        }
    }
    return result;
}

Example: PlusOut

plusOut("1xy2", "xy");
  • To do this we need a while loop otherwise it get confusing (6-21)
  • Phew that was a lot of work!
  • Looking at it now it is hard to understand all at once!
  • But step-by-step is approachable
String plusOut(String s, String word) {
    // Create a new string to return
    String result = "";
    // All characters in s replaced with +
    int i = 0;
    while (i < s.length()) {
        String nextN = "";
        if (word.length() + i <= s.length()) {
            for (int j = i; j < word.length() + i; j++) {
                nextN += s.charAt(j);
            }
        }
        // Except for appearances of word
        if (nextN.equals(word)) {
            result += nextN;
            i += word.length();
        } else {
            result += '+';
            i++;
        }
    }
    return result;
}