while loops, Strings, and fencepost
	loopswhile loops, Strings, and fencepost
	loopsExcept where otherwise noted, the contents of this document are Copyright 2010 Stuart Reges and Marty Stepp.
lab document created by Whitaker Brand and Marty Stepp
Goals for today:
Strings to represent and manipulate text data
	while loops for indefinite repetition
	 
	  
	String Methods| Method name | Description | 
|---|---|
| charAt(index) | character at given index | 
| indexOf(str) | index where the start of the given Stringappears in this
	string (-1 if not found) | 
| length() | number of characters in this String | 
| replace(str1, str2) | a new string with all occurrences of str1 changed to str2 | 
| substring(index1, index2)or substring(index1) | the characters in this string from index1 (inclusive) to index2 (exclusive); if index2 is omitted, grabs till end of string | 
| toLowerCase() | a new string with all lowercase letters | 
| toUpperCase() | a new string with all uppercase letters | 
    Write the results of each expression with Strings in
    "quotes" and characters in single quotes ('a')
  
//       index 0123456789012345
String str1 = "Frodo Baggins";
String str2 = "Gandalf the GRAY";
  | str1.length() | 13 | |
| str1.charAt(7) | 'a' | |
| str2.charAt(0) | 'G' | |
| str1.indexOf("o") | 2 | |
| str2.toUpperCase() | "GANDALF THE GRAY" | |
| str1.toLowerCase().indexOf("B") | -1 | |
| str1.substring(5) | " Baggins" | |
| str2.substring(3, 14) | "dalf the GR" | |
| str2.replace("a", "oo") | "Goondoolf the GRAY" | |
| str2.replace("gray", "white") | "Gandalf the GRAY" | |
| "str1".replace("r", "range") | "strange1" | 
We are once again going to download a program from the textbook that we will use for a debugging exercise. To do so, follow these steps:
Hailstone.java in jGRASP.
      
    We are going to practice setting stops and continuing execution.  We will
    explore Hailstone.java.  This program computes a sequence
    known as a hailstone sequence.  This is related to an unsolved problem in
    mathematics known as the
    Collatz
    Conjecture.
  
To complete these problems, you will want to set breakpoints and to use the "Resume" button that resumes execution. The "Resume" button is the one that uses a standard "play" icon (the sixth one from the left below):
continued on the next slide...
    The first call on the method asks it to compute the sequence starting with
    the value 7.  Set a stop that will allow you to determine the first five
    values that the variable value takes on not counting the
    initial value of 7.
  
| Initial | 7 | 
|---|---|
| next value | 22 | 
| next value | 11 | 
| next value | 34 | 
| next value | 17 | 
| next value | 52 | 
continued on the next slide...
You should still be in the middle of the first execution of the method. Clear your old stop by clicking on it a second time and set a stop for the second method call in main. Then resume execution. You should end up back in main just before the second call is made.
    Now we want to determine the sequence of values that the
    variable min takes on in this second call.  It is initialized
    to the first value of 7 and is reset when a new minimum is encountered.
    Set a stop that will allow you to determine the first four values that the
    variable min takes on not counting the initial value of 7.
  
| Initial | 7 | 
|---|---|
| next value | 5 | 
| next value | 4 | 
| next value | 2 | 
| next value | 1 | 
while loop
    basicsConsider the following loop.
int x = 1;
System.out.print(x);
while (x < 100) {
    x = x + x;
    System.out.println(", " + x);
}
  
    How many times does the code in the body while loop above
    execute?
    
    7
  
What output is produced? 1, 2, 4, 8, 16, 32, 64, 128
while loop
    mysteryFill in the boxes at right with the output produced by each method call.
| 
public static void mystery(int x, int y) {
    int z = 0;
    while (x % y != 0) {
        x = x / y;
        z++;
        System.out.print(x + ", ");
    }
    System.out.println(z);
}
 | 
 | 
while loop
    mysteryFill in the boxes at right with the output produced by each method call.
| 
public static void mystery2(int x) {
    int y = 1;
    int z = 0;
    while (2 * y <= x) {
        y = y * 2;
        z++;
    }
    System.out.println(y + " " + z);
}
 | 
 | 
while loop
    mysteryFill in the boxes at right with the output produced by each method call.
| 
public static void mystery3(int x) {
    int y = 0;
    while (x % 2 == 0) {
        y++;
        x = x / 2;
    }
    System.out.println(x + " " + y);
}
 | 
 | 
 
    
  repl that accepts a String
      and a number of repetitions as parameters and returns
      the String concatenated that many times. For example, the
      call repl("hello", 3)
      returns "hellohellohello". If the number of repetitions is 0
      or less, an empty string is returned.
     
    
  printLetters that takes
      a String as its parameter and that prints the letters of the
      String, separated by commas.  For example, the call
      of printLetters("Rabbit") should print:
      R, a, b, b, i, t
String object has a length method that
      tells you how many characters are in the String and
      a charAt method that gets you individual characters of
      the String.)
    
public static void printLetters(String text) {
    if (text.length() > 0) {
        System.out.print(text.substring(0, 1));   // fencepost
        for (int i = 1; i < text.length(); i++) {
            System.out.print("-" + text.substring(i, i + 1));
        }
        System.out.println();   // to end the line of output
    }
}
 
    
  lastDigit that returns the last digit
      of an integer.  For example, lastDigit(3572) should
      return 2.  It should work for negative numbers as well.  For
      example, lastDigit(-947) should return 7.
     
    
  firstDigit that returns the first digit
      of an integer.  For example, firstDigit(3572) should
      return 3.  It should work for negative numbers as well.  For
      example, firstDigit(-947) should return 9.
     
    
  season that takes two integers as
      parameters representing a month and day and that returns a String
      indicating the season for that month and day. Assume that months are
      specified as an integer between 1 and 12 (1 for January, 2 for February,
      and so on) and that the day of the month is a number between 1 and 31.
    "Winter". If the date falls between 3/16 and 6/15,
      you should return "Spring". If the date falls between 6/16
      and 9/15, you should return "Summer". And if the date falls
      between 9/16 and 12/15, you should return "Fall".
     
    
  printAverage that accepts
      a Scanner for the console as a parameter and repeatedly
      prompts the user for numbers. Once any number less than zero is typed,
      the average of all non-negative numbers typed is displayed. Display the
      average as a double, and do not round it. For example, a call to your
      method might look like this:
      Scanner console = new Scanner(System.in); printAverage(console);The following is one example log of execution for your method:
Type a number: 10 Type a number: 15 Type a number: -1 Average was 12.5If the first number typed is negative, do not print an average.
 
    
  digitSum that accepts an integer as a
      parameter and returns the sum of the digits of that number.  For example,
      the call digitSum(29107) returns 2+9+1+0+7 or 19.  For
      negative numbers, return the same value that would result if the number
      were positive. For example, digitSum(-456) returns 4+5+6 or
      15.  The call digitSum(0) returns 0.
    use / 10
      and % 10 operations.)
    
public static int digitSum(int n) {
    n = Math.abs(n);            // handle negatives
    int sum = 0;
    while (n > 0) {
        int lastDigit = n % 10;
        sum = sum + lastDigit;  // add last digit to sum
        n = n / 10;             // remove last digit from n
    }
    return sum;
}
 
    
  
    Write a method named hopscotch that accepts
    an integer parameter for a number of "hops" and prints a hopscotch board of
    that many hops.
  
    For example, the call hopscotch(3); would produce the
    following output:
  
1 2 3 4 5 6 7 8 9 10
Try solving this problem in Practice-It: click on the check-mark above!
 
    
  
    Write a method named longestName that reads
    names typed by the user and prints the longest name (the name that contains
    the most characters) in the format shown below. Your method should accept a
    console Scanner and an integer n as parameters and
    should then prompt for n names.
  
    A sample execution of the call longestName(console, 4) might
    look like the following:
				
name #1? roy name #2? DANE name #3? sTeFaNiE name #4? Erik Stefanie's name is longest
Try to solve this problem in Practice-It: click on the check-mark above!
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 
public class StringOops {
    public static void main(String[] args) {
        Scanner console = new Scanner(System.in);
        System.out.print("Type your name: ");
        String name = console.nextString();
        process(name);
    }
    public static void process(string "name") {
        if (name == Whitaker) {
            System.out.println("You must be really awesome.");
        }
        replace("a", "e");
        toUppercase(name);
        name.substring(0, 3);
        System.out.println(name + " has " + name.length + " letters");
    }
}
 | 
nextString should be nextstring should be Stringname should not be in quotesWhitaker should be in quotes==; must
      use .equalsreplace without specifying a string
      object (name)toUppercase should be
      toUpperCasename. should come
      before toUpperCase, not passed as a parameter to itname = to store the result
      of toUpperCasename = to store the result
      of substring() when
      calling length
public class StringOops {
    public static void main(String[] args) {
        Scanner console = new Scanner(System.in);
        System.out.print("Type your name: ");
        String name = console.next();
        process(name);
    }
    public static void process(String "name") {
        if (name.equals("Whitaker")) {
            System.out.println("You must be really awesome.");
        }
        name = name.replace("a", "e");
        name = name.toUpperCase();
        name = name.substring(0, 3);
        System.out.println(name + " has " + name.length() + " letters");
    }
}
Copy/paste and save this program in jGRASP, then go to the next slide.
import java.util.*;  // for Scanner
public class ProcessName {
    public static void main(String[] args) {
        Scanner console = new Scanner(System.in);
        System.out.println("Type your name: ");
        
        // your code goes here
        
        System.out.println("Your name is: " + name);
    }
}
  
Type your name: Jessica Miller
Your name is: Miller, J.
    
import java.util.*;  // for Scanner
public class ProcessName {
    public static void main(String[] args) {
        Scanner console = new Scanner(System.in);
        System.out.println("Type your name: ");
        
        // your code goes here
        String name = console.nextLine();
        int space = name.indexOf(" ");
        String first = name.substring(0, space);
        String last = name.substring(space + 1, name.length());
        String firstInitial = first.substring(0, 1);
        name = last + ", " + firstInitial + ".";
        
        System.out.println("Your name is: " + name);
    }
}
    
    Modify your ProcessName program so that it re-prompts until
    the user types a name that is at least 5 letters total in length and has at
    least one space in it.  Example:
  
Type your name: Joe Error, must be at least 5 chars with a space. Type your name: O K! Error, must be at least 5 chars with a space. Type your name: what Error, must be at least 5 chars with a space. Type your name: Tyler Durden Your name is: Durden, T.
import java.util.*;  // for Scanner
public class ProcessName2 {
    public static void main(String[] args) {
        Scanner console = new Scanner(System.in);
        System.out.println("Type your name: ");
        String name = console.nextLine();
        
        while (name.length() < 5 || name.indexOf(" ") < 0) {
            System.out.println("Error, must be at least 5 chars with a space.");
            System.out.println("Type your name: ");
            name = console.nextLine();
        }
        
        int space = name.indexOf(" ");
        String first = name.substring(0, space);
        String last = name.substring(space + 1, name.length());
        String firstInitial = first.substring(0, 1);
        name = last + ", " + firstInitial + ".";
        System.out.println("Your name is: " + name);
    }
}
 
    
  printFactors that accepts an integer as
    its parameter and uses a fencepost loop to print the factors of that
    number, separated by the word "and". For example, the
    call printFactors(24) should print as the following output:
  1 and 2 and 3 and 4 and 6 and 8 and 12 and 24
 
    
  swapPairs that accepts
      a String as a parameter and returns that String
      with each pair of adjacent letters reversed.  If the String
      has an odd number of letters, the last letter is unchanged.  For example,
      the call swapPairs("forget") should
      return "ofgrte" and the call swapPairs("hello
      there") should return "ehll ohtree".
    If you finish all the exercises, try out our Practice-It web tool. It lets you solve Java problems from our Building Java Programs textbook.
You can view an exercise, type a solution, and submit it to see if you have solved it correctly.
Choose some problems from Chapter 5 and try to solve them!