Welcome to Lesson 14!


Learning Objectives
By the end of today's class, you should know...

  • How do you trace a nested loop?
  • How do you use a for loop, the length method for a String and the charAt method to iterate through a String, character-by-character?
  • How do you use the substring() method for a String?
    • What type does it return (char or String)?
  • What is the problem caused by newline characters when mixing next(), nextInt() and nextDouble() with nextLine()?

Announcements

  • Quiz 5 after the break
  • Don't forget Lab 7 due tomorrow!

Review Questions
Find a partner and answer the following question:
1. Rewrite the below while loop as the equivalent for loop:
int count = 0;
while (count < 10) {
    System.out.println(count);
    count++;
}
2. What will be the output of the following code:
for (int i = 0; i <= 5; i++){
        if (i % 2 == 0)
            System.out.print("$");
        else
            System.out.print("!");
    }


Nested Loops

About Nested Loops
  • Some looping applications have loops nested within other loops
  • For example, you may use a nested loop to print a table of values
  • The following example shows a simple table created with nested loops
  • Let's follow the execution sequence before checking the result

Example of Nested Loops

1
2
3
4
5
6
7


for (int outer = 1; outer < 4; outer++)
{
    for (int inner = 1; inner < 4; inner++)
    {
            System.out.println(outer + " " + inner);
    }
}

Tracing the Variables

  • To understand a looping application, you need to trace the loop by hand
  • To trace the loop, write the variables used in the loop as headings across a page
  • On the first line under the headings, write the initial values
  • Execute the loop 3-5 times and record the values of the variables each time through the loop
  • Pay especial attention when entering the loop the first time and when ending the loop
  • You can slightly modify the computations if it helps to test the loop
  • Below is an annotated trace of the variables for the inner and outer loops
  • Note that the outer loop changes only after the inner loop is finished
Memory Screen 
 outer  inner  
  1  11 1
   21 2
   31 3
   4 (end of loop)   
  2  12 1
   22 2
   32 3
   4 (end of loop)   
  3  13 1
   23 2
   33 3
   4 (end of loop)   
  4 (end of loop)     
  • By analogy, nested loops are like an odometer on a car
  • The inner loop is like the digit to the right on an odometer
  • The numbers to the right loop completely before the number to the left increments by one

Nested Loop Example: Drawing Squares
  • Another example of a nested loop is to draw a square using stars ("*")
  • Remember our bar graph example with the for loop?
  • Copy and paste the following code into your Netbeans Loopy program, compile and run it.
    package loopy;

    /**
    *
    * @author Jennifer Parrish
    */
    import java.util.Scanner;

    public class Loopy {

    /**
    * @param args the command line arguments
    */
    public static void main(String[] args) {

    int size = 0;
    Scanner input = new Scanner(System.in);

    System.out.print("Enter a number and I will show its"
    + " bar graph.\nEnter your number: ");
    size = input.nextInt();
    System.out.println();

    for (int row = 1; row <= size; row++)
    {
    System.out.print("*");
    }
    System.out.println();

    }

    }

  • Now, let's alter the program to contain a nested for loop.
  • We will place another for loop inside the first one.
  • The nested loop makes the bar graph print in 2D.
  • The code for drawing a square consists of two loops, one nested inside the other:
    for (int row = 1; row <= size; row++)
    {
        for (int col = 1; col <= size; col++)
        {
            System.out.print("*");
        }
        System.out.println();
    }
    
  • The code is easier to read from the inside out
  • The inner loop draws a line of characters across the screen from left to right
  • At the end of the inner loop we print a newline to end the line of characters
  • The outer loop controls the number of lines to draw
  • Note how the inner loop is indented to make the structure clear
  • The inner loop is controlled by the outer loop, which is why it is indented
  • The inner loop in turn controls other statements, which ends up indenting yet again
  • Whenever you type an opening brace ({) you should indent the next character
  • Whenever you type a closing brace (}) you should remove the indentation (outdent)

Example Program to Draw Squares

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

package loopy;

/**
*
* @author Jennifer Parrish
*/
import java.util.Scanner;

public class Loopy {

/**
* @param args the command line arguments
*/
public static void main(String[] args) {

int size = 0;
Scanner input = new Scanner(System.in);

System.out.print("Enter a number and I will print a square."
+ "\nEnter your number: ");
size = input.nextInt();
System.out.println();

for (int row = 1; row <= size; row++)
{
for (int col = 1; col <= size; col++)
{
System.out.print("*");
}
            
System.out.println();
         }
}

}
  • We can make the square hollow by using an if statement inside the inner loop to decide when to print characters
  • Develop test conditions that allow the characters to print only at the start and end of the columns and rows
  • Use an else clause to print spaces when not printing characters
  • Another example of a nested loop is to draw a triangle, which we explore in the next exercise

Activity 14.1: Tracing a Nested Loop (10 pts)

In this exercise we explore how nested loops work by tracing the execution of a loop in a program. Part of the trace will involve use of the Boolean "or" (||) operator we discussed last class.

Specifications

  • Find a partner.
  • Take out a piece of paper, put your name on it and draw a grid like this:

rowcol#12345
11 21*    
21 2 32**   
  3     
  4     
  5     
  • Leave extra room for the col column as shown. The right hand area is for drawing the shape where the row and column headings match the row and col variables of the program.
  • For the code snippet listed below, trace the loop variables and write the values of the loop variables on the paper as your trace progresses for 5 rows. In addition, draw on your paper the shape printed by the nested loops in the program. Do NOT run the program.
  • You can see the trace for the first few entries in the grid above. As you trace the program, cross out the col entries as you update them, as shown. However, make each row change start on a new row so that the graph on the right lines up with the row entries.
1
2
3
4
5
6
7
8
9
10
11
12
13
14

for (int row = 1; row <= 5; row++)
{
    for (int col = 1; col <= row; col++)
    {
        if (col == 1 || row == col || row == 5)
        {
            System.out.print("*");
        }
        else
        {
            System.out.print(".");
        }
    }
    System.out.println();
}
  • Draw the output into the text box under the activity on Canvas.
  • The instructor will trace it on the board when everyone is finished.

Strings Continued

Review: Strings Versus Characters

  • Remember that a string is a series of characters enclosed in double quotes such as:
    "Hello"  "b"  "3.14159"  "$3.95"  "My address is 378 Eastbrook Dr"
  • We can store text in a variable of type string, like:
    String firstName;             // declaration
    firstName = "Jennifer";       // assignment
    String lastName = "Parrish";  // declaration + assignment
    String fullName = firstName + " " + lastName; // concatenation (+) of 2 stings
    
  • On the other hand, a character is a single letter, number or special symbol
  • We enclose characters in a single quote, rather than a double quote, like:
    'a'   'b'   'Z'   '3'   'q'   '$'   '*'
  • Also, we can store a a single character using a variable of type char, such as:
    char letterA = 'A';
    char letterB = 'B';
    
  • By declaring a char variable or using single quotes, Java knows to treat the number as a character
  • Thus, when we print a character, we see a letter rather than a number:
    char letter = 'A';
    System.out.println(letter + 'B');
    
  • As we can see, a string is made up of characters and characters are numerical codes
  • We can use this information to work with characters and strings

Indexing a String

  • Strings have a built-in indexing system with each stored in a character sequence starting at 0 (zero)

String sport = "Basketball";


  • We can access any individual character of a String variable using the String method charAt(i)
  • The general syntax is:
    stringVariable.charAt(index);
  • Where:
    • stringVariable: the name of your string variable
    • index: the number of the character position
  • For example:
    String str = "abcdef";
    char firstLetter = str.charAt(0);
    System.out.println(""+firstLetter + str.charAt(1));
    
  • The above code displays:
    ab
  • Notice that the charAt method returns a char data type
  • What will the following print?
public static void main(String[] args) {
      String sport = "Basketball";
      System.out.println("The league: " + sport.charAt(1) + sport.charAt(7));

      System.out.println("Abbreviation for this sport: " + sport.charAt(0) + sport.charAt(6);

}


Using a For Loop to Iterate Strings
  • Recall that member method length() returns the number of characters in a string variable:
    String s = "abcdef";
    int n = s.length();
  • After we know the length, it is easy to iterate through the individual characters of a string using a counting loop:
    System.out.println("Enter a message: ");
    String msg;
    msg = input.nextLine();
    for (int i = 0; i < msg.length(); i++) {
        System.out.println("Index " + i + ": " + msg.charAt(i));
    }
    

Group Activity: Iterating Strings

  • Open a new Java project called Loopy or alter an existing one.
  • Add the following for-loop code to the main method.
    String msg = "Hello, world!";
    

    for (int i = 0; i < msg.length(); i++) {
        System.out.println("Index " + i + ": " + msg.charAt(i));
    }

    
    
  • Compile and run your code. What do you see when you compile?


The substring() Method

  • The substring(begin, end) method also uses index numbers to select part of a String:
    String greeting = "Hello, World!";
    String sub = greeting.substring(0, 4);
    System.out.println(sub); // does this print "Hell" or "Hello"?
    
  • The begin argument starts with the index number of the first character
  • The end argument is always one past the last character to extract
    H e l l o ,
    W o r l d !
    0 1 2 3 4 5 6 7 8 9 10 11 12
  • As another example, we can extract "World" using:
    String w = greeting.substring(7, 12);
    System.out.println(w);
    
  • Note from the example above that the substring() method returns a String not a char.
  • Which extracts the characters highlighted in the following diagram:
    H e l l o ,
    W o r l d !
    0 1 2 3 4 5 6 7 8 9 10 11 12
  • Note that you get a Runtime Exception (error) if you try to select an index lower than 0 or beyond the end of a string
  • For example, the code:
    char bogus = greeting.charAt(15);
    
    produces an error like:

    Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 15
            at java.lang.String.charAt(String.java:687)
            at StringMethods.main(StringMethods.java:13)


Activity 14.2: How many words in your sentence? (10 pts)

  • Let's write a program that counts the number of words in a sentence input by the user.
  • Find a partner and open up a new Java project called Words
  • Alter the block comments to contain your names and section information.
  • Next declare a String variable at the top of your program named sentence:
String sentence;
  • Welcome the user to the program with the following message:
Give me a sentence, and I will count the number of words.
  • Prompt the user to input a sentence and store the user input as the sentence variable.
    Please enter your sentence.
  • Don't forget to use input.nextLine() here to read in the entire sentence.
  • How can we determine how many words are in a sentence?
  • We need to look at the whitespace.
  • Next, we will use a for loop to scroll through the sentence looking for blank spaces. 
  • Each time we encounter a new blank space, we will add one to our total for the number of words in the sentence.
  • Create a new variable at the top of main to store our counter for the number of words in the sentence. Assign it a value of 1. Why do we want to give it an initial value of 1 not 0?
int numWords = 1;
  • Now, create a for loop to iterate through the sentence. Don't forget to use the length() method here.
for (int i = 0; i < sentence.length(); i++) {
      System.out.println(sentence.charAt(i));
}
  • Now, run your program and verify that you get the following output.



  • However, this is not the purpose of our program.
  • We want to count the number of words.
  • Remove the System.out.println() statement from your for loop.
  • Replace the System.out.print statement with an if statement to check the value of the the sentence at index i to determine if it is a blank space.

if (sentence.charAt(i) == ' ') //Why am I using == here and not equals()?

  • When we encounter a blank space, we need to add one to the numWords variable.
  • Your for loop should now look like this:

for (int i = 0; i < sentence.length(); i++) {
    if (sentence.charAt(i) == ' ') {
        numWords++; 
    }
}
  • Finally, outside of your for loop, add a statement to print out the number of words.
System.out.println("There are " + numWords + " words in \"" + sentence + "\"");

  • Your program should now look like this:
  • Let's see if we can also use the substring() method to print the individual words in the sentence.
  • Add a print statement above the for loop to print the following message:

The words in your sentence are:

  • Notice that the starting index of each word occurs at the index following the blank spaces in the sentence:
I

l
o
v
e

m
y

p
e
t
0
1
2
3
4
5
6
7
8
9
10
11
12

  • In the above example, the word "love" begins at index 2, the word "my" begins at index 7 and the word "pet" begins at index 10, one index after each blank space.
  • Also the previous word ends at the index right before each blank space.
  • We already know the location of the blank spaces due our if statement.

    if (sentence.charAt(i) == ' ')

    //i will be the index of a blank space if the condition is true

  • Now, let's put it all together to print out each word using the substring() method.
  • First, add a new variable declaration at the top of your program:

int start_index = 0;

  • Next, inside the if statement of the for loop, add a print statement like the following to print out each word:

System.out.println(sentence.substring(start_index, i));

  • Finally, beneath that print statement, let's reset the starting index for the next word in the sentence:

        start_index = i+1; //Why do we use i+1 here?

  • Try running your code. You should notice a problem here. Why does the last word not print out?
    • Hint: The last character of the sentence is a \n not a ' '.
  • Let's add one last print statement, outside the loop to print the last word:

System.out.println(sentence.substring(start_index, sentence.length()));

//why do I use sentence.length()?

  • Run it again and make sure you get the correct output:

  • Submit your program to Canvas when you are finished.
  • Your code should now look like the following:


Wrap Up

  • With your partner, answer the questions from today's learning objectives

Upcoming Assignments
  • Assignment 14 due Tuesday at 1:20pm on Canvas
  • Lab 7 due Friday at midnight