Computer Science 101B Lab 6b: Sorting Arrays and Strings
Due: Friday, October 27, 2000

Objectives and Overview: This lab continues your work with arrays, including sorting, and introduces some useful techniques for working with String values and variables.

Part 1 - Sorting Arrays

Here are three new methods that, together, sort the elements of any array of integers, i.e. rearrange them so that they are in ascending order.

  static void Sort (int[] A, int size) {
  //
    int i, j;
    for (i=1; i<size; i++) {
      // All elements in A[1]..A[i] are less than
      // all elements in A[i+1]..A[size], and
      // a[1]..A[i] is sorted.
      int min = findMinimum(A, i, size);
      swap(A, i, min);
    }
  }

  static int findMinimum (int[] A, int i, int size) {
  // find and return the index of the smallest element in A[i..size]
    int j, min = i;
    for (j=i+1; j<=size; j++)
      // A[min] <= all elements in A[i]..A[j-1]
      if (A[j] < A[min]) min = j;
    return min;
  }

  static void swap (int[] A, int i, int j) {
  // exchange (swap) the ith and jth elements of A
    int temp = A[i];
    A[i] = A[j];
    A[j] = temp;
  }

The sorting process works as a series of passes on the array A.  In each pass, the smallest element of a subarray, from position i to the end of A, is located and then swapped (exchanged) with the first element of that subarray.  There is one pass for each value of i from 1 to size-1.  Here is an example, with a 5-element array A (size = 5):
 

           A                         index of   Result of swap on A
Pass (i)   [1]  [2]  [3]  [4]  [5]   smallest   [1]  [2]  [3]  [4]  [5]
--------   ------------------------  --------   --------------------------
  1         3    5    2    7    4       3        2 |  5    3    7    4
  2         2    5    3    7    4       3        2    3 |  5    7    4
  3         2    3    5    7    4       5        2    3    4 |  7    5
  4         2    3    4    7    5       5        2    3    4    5 |  7
 
Here, the smallest element in the subarray A[i..size] is underlined in each pass; its index is located by the method FndMinimum.  The exchange is accomplished by the swap method.  The Sort method controls the process by looping through the correct number of passes.  At each pass, it simply calls findMinimum and swap.  The vertical bar (|)placed in the righthand list identifies that part of A which has been sorted at the end of each pass.  After the 4th pass, the entire array is sorted, since the 5th element is (by default) in its proper position.
 
You will adapt and use these Sorting methods in Part 3.

Part 2 - String Variables and Methods

The Java class String can support programming in a wide range of applications, such as word processors and spelling checkers.  Below is a summary of the String methods and their use.
String Constants and variables
A String constant is any sequence of characters enclosed in single double quotes ("). E.g., the following message is a String constant.

"Enter file name:  "

A String variable is any variable declared with the type String. The following are String variables:

String s, t, u;

The value of a String variable can be any String constant, including the empty String "" (the one that has no characters between the quotes).

The String class has a number of methods that allow programs to manipulate String values in different ways. The discussion below illustrates how some of these methods are used by showing some simple examples.

String Length, Assignment, Concatenation, and Comparison
The length of a String is the number of characters that appear between the quotes, including blanks and all other special characters.  String variables can be assigned values, just like numerical variables. This can be done with an assignment statement or a in.readname() statement. The following statement assigns a String value to the variable s declared above:

s = "Hello World!";

The length of s is 12, and the method length returns the length of any String. Thus, the expression s.length() returns 12 in this example.

The ith character of a String variable can be isolated by using the charAt method.  String values can be viewed as arrays of characters in this sense, so the expression s.charAt(0) returns the first character 'H', s.charAt(1) returns the second character 'e', and so forth. [Note that single characters are enclosed in single quotes (') rather than double quotes ("), which enclose strings. Thus the character H is written as 'H', while the 1-character String H is written as "H".]

Two String values can be concatenated (joined together) to form a single String, either using the + sign or using the concat method, which is part of the String class. Either of the following statements leaves the variable u with the value "Hello World! Hello!".

u = s + " Hello!";
u = s.concat(" Hello!");

Two String values can be compared for equality or nonequality using the equals method. Equality for String values means that one is an identical copy of the other, letter for letter. So we might write

if (s.equals("Hello!")) ...

to test whether or not the current value of s is identical to the String "Hello!".   A related method is called equalsIgnoreCase, which will be true if the two strings are identical except for capitalization differences.  For instance, if s=="Hello", then s.equals("heLLO") is false but s.equalsIgnoreCase("heLLO") is true.

To test whether one string precedes another in an alphabetical sense, the compareTo method can be used.  The expression s.compareTo("hello") returns a number < 0, 0, or > 0 depending on whether the value of s precedes, matches, or follows the string "Hello" alphabetically.  So, considering an array 'words' of strings, the following if statement would test to see if string words[i] follows words[j] in the dictionary, and if so swap them:

if (words[i].compareTo(words[j]) > 0))
   swap(words, i, j);

This example assumes, of course, that we have a method swap that will exchange the values of two entries in an array of strings.

Substring Extraction, Insertion, and Deletion
A String can be formed by extracting a copy of an embedded String, called a substring, from another string. For example, the following statement extracts a copy of "World" from the String s and assigns it to the String t::

t = s.substring(6, 11);

Here, the 6 designates the starting position of the substring to be copied, and the 11 designates the position of the next character in s following the substring (counting the first character at position 0, not 1). Note that the value of s itself is not affected by this action.

If we wanted to delete that same substring from s, we would need to concatenate the beginning part of s with that part which follows that substring. That is, we would write

s = s.substring(0, 5) + s.substring(11);

to obtain the string "Hello" and assign it to s. Note here that the expression s.substring(11) takes that substring which begins at position 11 and ends at the end of s. That is, it is the entire righthand end of s.

Finally, to insert a new substring within an existing String, we use concatenation and substring in a different way.  For instance, to insert the word "Cruel" inside the string s = "Hello World!" to form s = "Hello Cruel World!" we would write the following assignment:

s = s.substring(0, 5) + " Cruel " + s.substring(6);

String Searching and Replacement
Two other useful String methods search a String for the position of a particular character or substring that may occur within it, and replace a character within a String by another character. The first is called indexOf, and the second is called replace. Here are two examples (assuming i and j are integer variables, and s has the value "Hello Cruel World!").

i = s.indexOf("Cruel");
s = s.replace(s.charAt(i), 'c');

The resulting value of i in this example is 6 (the position of the first character of the leftmost occurrence of the substring "Cruel" within s). The resulting value of s is "Hello cruel World!" since s.charAt(i) returns the character 'C'.  Here are some simple exercises to check your understanding of the above ideas.

  1. Write a Java statement that locates the position of the first blank character in String sourceString and assigns it to the integer variable indexFirstBlank. Using this value of indexFirstBlank, write statements that extracts the first word from sourceString and assign it to the String firstWord. That is, if sourceString has the value "Hello Cruel World", your statements should result in firstWord having the value "Hello" and sourceString having the value "Cruel World".

  2.  
  3. Create a method removeBlanks(String sourceString) that takes a String and creates and returns a String which is the same as String sourceString but with all its blanks removed. For instance, if testString has the value "Hello Cruel World", then the method call removeBlanks(testString) should return the String "HelloCruelWorld".

  4.  
  5. Design a method makeLowerCase(String sourceString) that takes a String, creates a new String that is the same as the input String except that all upper-case letters have been replaced with lower-case letters, and returns that new String. For example, if testString has the value "THE Brain", the method call makeLowerCase(testString) should return the String "the brain".

Part 3 - Further Refinements on the Word List Program - A Complete Indexing Program

Alter the three Sorting methods so that they can sort Strings. Once you have done this, you can use them to sort the arrays words and counts in your word list program so that words is in alphabetical order.  Note that whenever a pair of words is swapped inside the words array, the corresponding counts in the counts array must be swapped as well.  That is, each word must remain "in parallel" with its frequency count.  Using the adapted Sorting methods and the String method you developed in Part 2, Question 3, refine your word list program so that it:

Lab 6 Deliverables:

  • For Part 2, put your answers in a Java program, i.e. your program should have the statements required by Question 1 in the main method and two additional methods: removeBlanks(String sourceString) and makeLowerCase(String sourceString). Demonstrate that your statements and methods work by executing them on the examples in the questions and displaying the results on the screen. Submit a hard copy of the program and the output. Also, drag a hard copy of the program to the CS101b (Majercik) --> Drop Box.
  • For Part 3, turn in a hard copy of the program that you developed along with printouts of the output on the two smaller test files (tiny and poem). Also, drag a hard copy of this program to the CS101b (Majercik) --> Drop Box.

  •