import java.util.Scanner; import java.util.Random; import java.io.File; import java.io.FileNotFoundException; /* Java application whose purpose is to test the Java class RedBluePartitioner, ** instances of which partition arrays containing values 'R' and 'B' ** (RED and BLUE, respectively) so that all the R's come first, followed ** by the B's. ** The user is prompted to enter, for each color, how many elements of that ** color are to be placed into the array to be partitioned. The values are ** placed into the array in pseudo-random order, a clone is made of the ** array, and then RedBluePartitioner's partition1() and partition2() ** methods are applied to the array and its clone, respectively. The ** results of partitioning are displayed. ** Note that the user is prompted to enter a seed to be used in creating ** the Random object; the seed value determines the order in which the array ** elements occur. Thus, by choosing the same seed on different runs of ** the program, the same array will be partitioned each time. */ public class RB_Partition_Tester { private static Scanner keyboard; private static boolean echo; public static void main(String[] args) throws FileNotFoundException { String promptSuffix = " to put in the array: "; String redPrompt = "Enter # of RED elements"; String bluePrompt = "Enter # of BLUE elements:"; String randPrompt = "Enter (int) seed for pseudo-random # generation: "; System.out.println("Welcome to the RedBluePartitioner tester program!"); // If a command line argument is provided, interpret it to be the // name of a file containing input data. if (args.length > 0) { File file = new File(args[0]); keyboard = new Scanner(file); echo = true; } else { keyboard = new Scanner(System.in); echo = false; } int numRed = getInt(redPrompt + promptSuffix); int numBlue = getInt(bluePrompt + promptSuffix); int randSeed = getInt(randPrompt); Random rand = new Random(randSeed); char[] a = randomArray(rand, numRed, numBlue); System.out.println("Array to be partitioned:"); displayArraySegment(a, 0, a.length); System.out.println(); // Make a clone of a[] so that the partition1() and partition2() // methods can be applied to identical arrays. char[] aClone = a.clone(); // Create a RedBluePartitioner object p RedBluePartitioner p = new RedBluePartitioner(); try { // Partition a[] using p.partition1() and then report the results. p.partition1(a); System.out.println("\nAfter calling partition1(), we have:"); reportResults(a, p); } catch (Throwable e) { e.printStackTrace(System.out); } System.out.println(); try { // Partition aClone[] using p.partition2() and then report the results. p.partition2(aClone); System.out.println("After calling partition2(), we have:"); reportResults(aClone, p); } catch (Throwable e) { e.printStackTrace(System.out); } } /* Displays the results of most recent partitioning. */ private static void reportResults(char[] ary, RedBluePartitioner part) { System.out.print("Partitioned array: "); displayArraySegment(ary, 0, ary.length); System.out.println(); int rbBoundary = part.blueStart(); System.out.printf("RED segment [%d,%d): ", 0, rbBoundary); displayArraySegment(ary, 0, rbBoundary); System.out.println(); System.out.printf("BLUE segment [%d,%d): ", rbBoundary, ary.length); displayArraySegment(ary, rbBoundary, ary.length); System.out.println(); System.out.println("# comparisons: " + part.numComparisons()); System.out.println("# swaps: " + part.numSwaps()); } /* Prints the specified string and returns the response entered at the ** keyboard, interpreted as an integer. */ private static int getInt(String prompt) { System.out.print(prompt); int result = keyboard.nextInt(); if (echo) { System.out.println(result); } return result; } /* Prints the values in the specified array segment (i.e., z[low..high)). */ private static void displayArraySegment(char[] z, int low, int high) { for (int i = low; i != high; i++) { System.out.print(z[i]); } } /* Returns a new array of type char[] containing the specified number ** of 'R' and 'B' values, put into pseudo-random order using the given ** Random object. */ private static char[] randomArray(Random r, int redCount, int blueCount) { int N = redCount + blueCount; // length of array to create char[] result = new char[N]; fill(result, 0, redCount, 'R'); fill(result, redCount, N, 'B'); permute(result, r); return result; } /* Places the specified value into each element of the specified ** array segment (i.e., a[low..high)). */ private static void fill(char[] a, int low, int high, char value) { for (int i = low; i < high; i++) { a[i] = value; } } /* Permutes the elements of the given array pseudo-randomly, using ** the given Random object. */ private static void permute(char[] a, Random rand) { for (int i = a.length; i > 1; i--) { // Swap the value at location i-1 with that at some location // in the range [0..i). int randLocation = rand.nextInt(i); swap(a, i-1, randLocation); } } /* Swaps the elements at the specified locations of the specified array. */ private static void swap(char[] a, int j, int k) { char temp = a[j]; a[j] = a[k]; a[k] = temp; } }