slanted W3C logo

Labtest 2 Practice Questions

Q1

Tests your ability to use charAt and to write loops.

Write a Java program that repeatedly asks a user for a line of text until the user enters the string done. The program counts the number of pairs of repeated characters; for example the string:

running sunning paddle waffle woof

has 5 pairs of repeated characters (shown in red). The program should find all pairs of repeated characters (not just letters) including repeated spaces. A character can only belong to one pair; for example the string aaa has only one pair of repeated a's (the first pair) and the string aaaa has two pairs of repeated a's.

Hint: Try to solve the counting part of the problem first (ie. only ask the user for a string once). Once you solve the counting part of the problem, put it inside of a sentinel guarded loop that repeatedly asks for a line until the user enters done.

Hint: The counting part can be solved by using a loop that processes the string from left to right using charAt.

My solution:

import java.io.PrintStream;
import java.util.Scanner;

public class Practice1
{
   public static void main(String[] args)
   {
      PrintStream output = System.out;
      Scanner input = new Scanner(System.in);
      
      final String DONE = "done";
      
      output.println("Enter a line of text");
      String line = input.nextLine().trim();
      
      for (; !line.equals(DONE); )
      {
         int numRepeats = 0;
         
         // The tricky part is getting this loop correct.
         // Notice that you look at the character at
         // index i and index i + 1 using charAt. You have
         // to be make sure that i + 1 is less than the
         // length of line, otherwise you will get an
         // exception which is why the conditional-part is:
         //
         // i < line.length() - 1;
         //
         // Also, notice that you have to skip over 2
         // characters if you find a repeated pair which
         // is why i is updated inside the body of the
         // loop instead of in the update part of the loop.
         for (int i = 0; i < line.length() - 1; )
         {
            char ci = line.charAt(i);
            char cj = line.charAt(i + 1);
            if (ci == cj)
            {
               numRepeats++;
               i = i + 2;
            }
            else
            {
               i = i + 1;
            }
         }
         output.printf("%d repeated characters%n%n", numRepeats);
         output.println("Enter a line of text");
         line = input.nextLine().trim();
      }
   }
}

Q2

Tests your ability to use indexOf and substring in a variable length code problem, and to write a loop.

Question 6.17 from the textbook. Write your program so that it repeatedly asks the user for a string until the user enters the string done.

Hint: Use the variable length code technique.

Consider trying the inverse problem: given a string such as SevenTwoFour output the equivalent string using digits (ie. 724). Ultimately, you still want to use the variable length code technique. The problem you need to solve is how do you isolate the numbers from the input string given that they are not separated by a separator character. Note that you determine if a charater is in uppercase by using the static method in the Character class named isUpperCase.

My solution:

import java.io.PrintStream;
import java.util.Scanner;

public class Practice2
{
   public static void main(String[] args)
   {
      PrintStream output = System.out;
      Scanner input = new Scanner(System.in);
      
      final String WORDS = "One  " +
                           "Two  " +
                           "Three" +
                           "Four " +
                           "Five " +
                           "Six  " +
                           "Seven" +
                           "Eight" +
                           "Nine " +
                           "Zero ";
                           
      final String NUMS  = "1    " +
                           "2    " +
                           "3    " +
                           "4    " +
                           "5    " +
                           "6    " +
                           "7    " +
                           "8    " +
                           "9    " +
                           "0    ";
      final int SIZE = 5;
      
      final String DONE = "done";
      
      output.println("Enter a string of digits");
      String line = input.nextLine().trim();
      
      for (; !line.equals(DONE); )
      {
         // not part of the question
         String regex = "\\d+";
         if (line.matches(regex))
         {
            for (int i = 0; i < line.length(); i++)
            {
               char ci = line.charAt(i);
               int index = NUMS.indexOf(ci);
               String word = WORDS.substring(index, index + SIZE).trim();
               output.print(word);
            }
            output.println();
         }
         else
         {
            output.println("Not a string of digits");
         }
         output.println("Enter a string of digits");
         line = input.nextLine().trim();
      }
   }
}

Q3

Tests your ability to use indexOf, charAt, substring, toLowerCase, string buffer, to write loops, and to use an if statement.

Question 6.18 from the textbook. Write your program so that it repeatedly asks the user for a string until there is no more input (ie. the user hits Ctrl-D in Linux or Ctrl-Z in Windows).

Write your program so that it first makes an all lowercase version of the string entered by the user. Your program should repeatedly use indexOf to find all of the ei substrings in the lowercase version of the string; when such a substring is found, you would use charAt to check if it is preceded by the letter c. You should use a string buffer to build the corrected string.

Hint: Try to solve the correction part of the problem first (ie. only ask the user for a string once). Once you solve the correction part of the problem, put it inside a loop that repeatedly asks the user for a string.

Hint: The correction part of the problem needs a loop to repeatedly look for ei substrings in the string.

My solution:

import java.io.PrintStream;
import java.util.Scanner;

public class Practice3
{
   public static void main(String[] args)
   {
      PrintStream output = System.out;
      Scanner input = new Scanner(System.in);
      
      final char C = 'c';
      final String EI = "ei";
      output.println("Enter a line of text:");
      
      for (; input.hasNext();)
      {
         String line = input.nextLine();
         
         // Make a lowercase version of line so that you don't
         // have to worry about case
         String lowerCase = line.toLowerCase();
         
         // You need to modify characters in the user-input string
         // so it's easier to use a string buffer
         StringBuffer fixed = new StringBuffer(line);
         
         // A loop to look for all of the "ei" substrings in lowerCase
         int prevIndex = 0;
         for (int index = lowerCase.indexOf(EI);
              index != -1;
              index = lowerCase.indexOf(EI, prevIndex))
         {
            // Only fix "ei" if it's not preceded by 'c'
            char charBefore = ' ';
            int before = index - 1;
            if (before > 0)
            {
               // if statement is needed in case "ei" happens
               // to be at the start of the line (in which
               // case before == -1 and charAt(before) will
               // throw an exception
               charBefore = lowerCase.charAt(before);
            }
            if (charBefore != C)
            {
               // ok, go ahead and swap the 'i' and 'e'
               char theE = fixed.charAt(index);
               char theI = fixed.charAt(index + 1);
               fixed.setCharAt(index, theI);
               fixed.setCharAt(index + 1, theE);
            }
            prevIndex = index + 1;
         }
         output.println(fixed);
      }
   }
}

Q4

Question 6.21 from the textbook.

This question is a lot easier than it looks. It can be solved using only the methods substring (or charAt, but substring saves you from having to convert a character to a string), replace, and length inside of a single loop.

Note: Question 6.23 from the textbook is almost identical to this problem but it cannot be solved so easily.

Q5

Question 6.22 from the textbook.

Hint: First use length to make sure the length of the string is a multiple of 3.

Hint: Use substring and equals to make sure the string starts with ATG. Alternatively, use startsWith.

Hint: Use a regular expression and matches to make sure the string is made up exclusively of the letters A, C, G, T.

Q6

The midterm question from last year.

The first thing you need to do is to read in the split letter as a string split and then trim the string split (to be safe). You can convert split to uppercase if you want.

The steps needed to process each full name are:

  1. Read in the full name as a string name
  2. Trim the string name
  3. Use indexOf to find the space in the name
  4. Use substring twice to extract the first and last names as first and last
  5. Use compareToIgnoreCase with split and last to figure out which room to send the person to

Q7

Write a program that asks the user for a string and replaces all instances of a date with today's date. You can assume that a date is always the 3-letter abbreviated name of the month followed by the day followed by a comma followed by the 4-digit year; for example Jan 12, 2003.

Use a regular expression and replaceAll. Your regular expression will probably match strings that are not necessarily dates, but that's ok. You do not need to use the Date class; just use a hard coded string for today's date.