Previous   Next


For simplicity and flexibility, we have used input and output sparingly in the programs in this tutorial. Most of our programs are ADT implementations intended for use with diverse clients, but we also exhibit the driver programs that you need to run and test the programs on your own data. Programs 1.1, 6.1, and 12.6 are typical examples. In these drivers:

The conventions for taking parameter values are standard in Java (and the mechanism is described in ); in this Appendix, we present the classes that we use for input and output. Rather than directly using Java library classes for input and output in our code, we use the adapter classes In and Out. The code for Out is trivial, since the methods that we use are precisely the methods that print a string (perhaps followed by a newline character) from Java's System.out class:

public class Out { public static void print(String s) { System.out.print(s); } public static void println(String s) { System.out.println(s); } } 

To use the programs in this tutorial that use the Out class, either put this code in a file named or just replace "Out"with "System.out" in the program code. The System.out class overloads print and println to take primitive-type parameters; we do not bother to do so because our client code usually prints strings and can otherwise easily use type conversion. The code for In is more complicated because we have to arrange for reading different types of data. (Type conversion for output is straightforward because of Java's convention that every type of data have a toString method that converts it to a string.) The following implementation of In is an adapter class for the Java StreamTokenizer class. It defines methods to initialize itself; read integers, floating point numbers, and strings; and test whether the input stream is empty:

import*; public class In { private static int c; private static boolean blank() { return Character.isWhitespace((char) c); } private static void readC() { try { c =; } catch (IOException e) { c = -1; } } public static void init() { readC(); } public static boolean empty() { return c == -1; } public static String getString() { if (empty()) return null; String s = ""; do { s += (char) c; readC(); } while (!(empty() | blank()));| while (!empty() && blank()) readC(); return s; } public static int getInt() { return Integer.parseInt(getString()); } public static double getDouble() { return Double.parseDouble(getString()); } } 

To use the programs in this tutorial that use the In class, put this code in a file named Our driver programs are intended for our own use in running and testing algorithms on known test data. Accordingly, we normally know that a program's input data is in the format that it expects (because we construct both the program and data in such a fashion), so we do not include error checking in In. Our programs explicitly initialize the input stream by calling In.init and test whether it is empty by calling In.empty, often just using the construct

for( In.init(); !In.empty(); ) 

with calls to one or more of the get methods within the body of the loop. The get methods return 0 or null rather than raising an exception if we attempt to read from an empty input stream, but our drivers do not make use of those return values. Using these adapter classes gives us the flexibility to change the way that we do input and output without modifying the code in the tutorial at all. While the implementations given here are useful in most Java coding environments, other implementations of In and Out might be called for in various special situations. If you have classes for input and output that you are accustomed to using, it will be a simple matter for you to implement appropriate In and Out adapter classes to replace the ones given here. Or, as you gain experience developing and testing the algorithms in this tutorial, writing the more sophisticated drivers called for in many of the exercises, you may develop more sophisticated implementations of these classes for your own use.

Previous   Next