Programming Assignment 3
Wrapper Classes, Text Processing, and Recursion with Merge Sort
Example Implementation
/**
* Implementation of Assignment 3: Wrapper Classes, Text Processing, and
* Recursion with Merge Sort
*
* @author Cheng, Jade
* @assignment CSCI 2912 Assignment 3
* @date Jan, 29, 2012
*/
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Scanner;
/**
* Implementation of Assignment 3: Wrapper Classes, Text Processing, and
* Recursion with Merge Sort
*/
public class ChengJade3 {
/**
* The main entry point of the program.
*
* @param args The command-line arguments.
*/
public static void main(final String[] args) {
assert null != args;
// Check if the wrong number of arguments are specified on the
// command line.
if (args.length != 1) {
System.err.println("Invalid command-line arguments.");
return;
}
// Read a list of floating-point values into this array list.
final ArrayList<Double> list = new ArrayList<Double>();
// Use a scanner to read the list of values, one per line; the values are
// boxed as they are added to the array list.
try {
final Scanner scanner = new Scanner(new File(args[0]));
while (scanner.hasNextLine()) {
// Read the next line from the file.
final String line = scanner.nextLine();
// If the line is empty, then display an error and terminate.
if (line.isEmpty()) {
System.err.println("Empty line encountered.");
return;
}
// Otherwise, attempt to parse the line as a double; if this fails,
// display an error and terminate.
try {
list.add(new Double(line));
} catch (final NumberFormatException e) {
System.err.println("Invalid line encountered: '" + line + "'.");
return;
}
}
} catch (final IOException e) {
// If an error occurs, display the error message and terminate.
System.err.println("Failed to read input file: " + e.getMessage());
return;
}
// Un-box the values from the array list.
final double[] array = new double[list.size()];
for (int i = 0; i < list.size(); i++)
array[i] = list.get(i).doubleValue();
// Sort the values using Merge Sort.
mergeSort(array);
// Print each value to standard output (in order).
for (final double value : array)
System.out.println(value);
}
/**
* Sorts the specified values using the merge sort algorithm.
*
* @param values The values to sort.
*/
private static void mergeSort(final double[] values) {
assert null != values;
// There is no need to sort an arrow zero length.
if (values.length == 0)
return;
// For efficiency, create a scratch array for temporary values.
final double[] scratch = new double[values.length];
// Merge-sort the entire array using recursion.
mergeSort(values, scratch, 0, values.length - 1);
}
/**
* Sorts the specified values using the merge sort algorithm.
*
* @param values The values to sort.
* @param scratch A scratch array, the same size as the list.
* @param min The lowest index in the array (inclusive).
* @param max The highest index in the array (inclusive).
*/
private static void mergeSort(
final double[] values,
final double[] scratch,
final int min,
final int max) {
assert null != values;
assert null != scratch;
assert values.length == scratch.length;
assert min >= 0;
assert max <= values.length;
assert min <= max;
// Check for the end case: The range is one element.
if (min == max)
return;
// Find the middle index of the range, and merge-sort both partitions.
final int lhsMax = (min + max) / 2;
final int rhsMin = lhsMax + 1;
mergeSort(values, scratch, min, lhsMax);
mergeSort(values, scratch, rhsMin, max);
// Copy the desired range from the values array to the scratch array.
System.arraycopy(values, min, scratch, min, 1 + max - min);
// Loop over both partitions in the scratch array, and copy the values
// in order back into the values array.
int lhs = min, rhs = rhsMin, dst = min;
while (lhs <= lhsMax && rhs <= max)
values[dst++] = scratch[lhs] < scratch[rhs]
? scratch[lhs++]
: scratch[rhs++];
// Copy the remaining items into the list.
while (lhs <= lhsMax)
values[dst++] = scratch[lhs++];
while (rhs <= max)
values[dst++] = scratch[rhs++];
}
}