Useful Java Hints For Programming Competitions: Bryce Kerley October 13, 2005
Useful Java Hints For Programming Competitions: Bryce Kerley October 13, 2005
Contents
1 Reading stu 1.1 From Console (STDIN) . . . . . . . . . . . . . . . . . . . . . . . 1.2 From File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3 With a Scanner . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 Writing stu 2.1 To Console . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.2 To File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 Strings 4 Big Numbers 4.1 Big Integers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 Data Structures 6 Classes and Methods 6.1 Static Methods and Variables . . . . . . . . . . . . . . . . . . . . 6.2 Member Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 Exceptions 8 Regular Expressions 1 2 2 2 2 2 3 3 3 3 4 5 5 6 6 8
Reading stu
import java.io.*; For line-by-line input, its quick and easy to use a BufferedReader. The readLine() method gives you a string from a single line of input, not including the newline at the end. BufferedReader in = new BufferedReader( //some Reader ); String line = in.readLine(); Where the lines come from is based on what Reader or Stream you load into the BueredReader object you instantiate. These same methods are used when reading from STDIN, a le, or even from a network socket.
1.1
BufferedReader in = new BufferedReader( new InputStreamReader(System.in) ); System.in is a pre-made InputStream hooked to STDIN, and you wrap it in an InputStreamReader to make it the Reader you can use with BufferedReader to read a line at a time.
1.2
From File
BufferedReader infile = new BufferedReader( new InputStreamReader( new FileInputStream( "filename" ) )); Just like from console, except you need a FileInputStream to turn the le into an InputStream too. Creating a FileInputStream can throw an Exception more about that later.
1.3
With a Scanner
Another option for reading is to use a Scanner (youll need to import it from java.util): Scanner in = new Scanner(System.in); int lol = in.nextInt(); double laff = in.nextDouble();
2
2.1
Writing stu
To Console
Writing is similar to reading, especially to STDOUT or STDERR: System.out.println("Note the lowercase l in println"); System.err.println("println() adds a newline, print() doesnt"); 2
Since System.out and System.err are both PrintWriters, its easy to see how wed rig a le to one.
2.2
To File
PrintWriter outfile = new PrintWriter( new OutputStreamWriter( new FileOutputStream( "filename" ) )); Using a PrintWriter object with your output le means you can use the same println() villany you do with STDOUT and STDERR. Just like a FileInputStream, a FileOutputStream can throw an Exception.
Strings
Strings are quite nice. They know their own length, can be split easily (in the most recent versions), concatentated easily, compared somewhat easily, etc. String lol = "lol"; System.out.println("lol is " + lol.length + " characters long."); String[] split = lol.split("o" System.out.println( "splitting lol on o: " + split[0] + " " + split[1]); if (lol.equals("lol")) System.out.println("lol is very lol"); Note that since a String is an object and not a base type, you cant use the == operation to compare them, since it compares to see if theyre the same instance and not holding the same content.
Big Numbers
This section requires java.math.* to be imported: import java.math.*; Sometimes you want a number way bigger than the basic data types (int, long, oat, double, etc.) can hold. If you dont mind sacricing the +-=*/% operators, you can use a BigInteger or BigDecimal.
4.1
Big Integers
The easiest way to construct a BigInteger is to feed it a string containing the number you want, with an optional radix. You can also use a static factory to make one from a long.
terrence = new BigInteger("124398015781115301532"); philip = new BigInteger(someInt + ""); scott = new BigInteger("0100101001110010101010010",2); celineDion = BigInteger.valueOf(someLong);
BigIntegers are capable of math operations! Who would have thought! BigInteger doctorMcCollum = BigInteger.valueof(someLong).add(BigInteger.ONE); doctorMcCollum = doctorMcCollum.multiply(BigInteger.ONE); doctorMcCollum = doctorMcCollum.pow(someInt); Some other fun methods: divide, remainder (might return a negative BigInteger), mod (never returns a negative), modPow (raises the BigInteger to the rst argument, and mods it by the second), gcd, and much more! toString is the method to output a BigInteger as a String, and if you call that with an int argument, itll even do it to that radix.
Data Structures
This section requires java.util.* to be imported: import java.util.*; Javas got a handful of pre-made data structures (known as collections) available so you dont have to re-implement them. What you need Set (no duplicates, no sorting, no keys) List (ordered/keyed by ints) Map (keyed by Objects) Sorted Set (sorted by Comparable members) Sorted Map (keyed by Comparable Objects) Stack (LIFO) Queue (FIFO) Priority Queue Use this HashSet ArrayList HashMap TreeSet TreeMap Stack LinkedList PriorityQueue
When using a collection in the most recent versions of Java, theyre declared with the kind of Object that theyre supposed to hold: ArrayList<String> zing = new ArrayList<String>(); zing.add(0,"blootoof"); //adds at 0 zing.add("pokey the penguin"); //adds at end System.out.println(zing.get(0)); //prints "blootoof" You can iterate through a collection using a for loop, as long as you dont modify the collection while youre in the loop:
for (String cur:zing) { System.out.println(cur); //prints each string in order } This works pretty well for most collections. If you want a way to iterate through a collection without caring about how the collection works, you can use an Iterator: Iterator i = zing.iterator(); while(i.hasNext()) System.out.println(i.next());
When writing a monolithic program supposed to t in one le/class (i.e. a solution for a competition problem hint hint), you miss out on the opportunity for organizing the application by separating classes into dierent les. However, since the code size is almost always less than 200 lines, you can skip the encapsulation parts of object-oriented design since the whole program will be worthless in ve hours anyways. This gives you the freedom to use really awful design practices like public member elds, static/global variables and methods, etc.
6.1
Youre going to be using these static methods just like functions in good ol C: public class Asdf { public static void main(String[] args) throws Exception { //so we dont have to catch them printSomething(); } public void printSomething() { System.out.println("Something"); } } In this example, printSomething() is a static method that can be called anywhere from Asdf. Global variables you say? Not in Java you say? Think small-scale! public class Jkl { public static int lols; public static void main(String[] args) throws Exception { 5
lols = 0; messWithLols(); System.out.println(lols); } public static void messWithLols() { lols+=120; } } This program prints 120 to the screen.
6.2
Member Classes
Want a C struct and the methods to cope with it? A dierent subclass of Object but cant make a new le for it? public class Qwerty { public static void main(String[] args) throws Exception { Zxcv z = new Zxcv; z.inc(); System.out.println(z.toString()); //prints 1 } public class Zxcv { private int batman; public Zxcv() { batman = 0; } //constructor public void inc() { batman++; } public String toString() { return (batman+""); // + "" is the lazy mans toString() for primitives } } } Caveat: You can use primitive+"" to do a cheap toString() on a primitive, but if you do it to an Object or one of its descendents, you might get in trouble.
Exceptions
Exceptions are what gets thrown when a function or operation makes a boo-boo. For example, BigInteger.divide() throws an ArithmeticException when
you divide by zero, and the get() method on many dierent collections throws one if what you want isnt there. Java forces you to either catch and handle exceptions (using a try/catch block), or specify in your function prototype that you might throw one. You might want to use them to identify a situation in which you need to calculate an entry for an array, or switch to a dierent algorithm for an exceptional situation (pun intended). try { BufferedReader in = new BufferedReader( new InputStreamReader( new FileInputStream ( "filename" ))); } catch (IOException e) { //this happens when an IOException is thrown in the try block System.out.println("IOException " + e.getMessage()); } catch (Exception e) { //this happens when a non-IOException is thrown above System.out.println("Exception " + e.getMessage()); } finally { //this happens when leaving the try or catch blocks System.out.println("Finally!"); } If no exceptions are thrown above, the contents of the try block will be executed rst, followed by the contents of the nally block. If an IOException is thrown during the try block, the rst catch block will run, then the nally block. If some other subclass of Exception gets thrown, the second catch block will run between the try and nally blocks. Lots of functions and constructors will require that you prepare for their exceptions - the compiler will whine about these situations. If you want to take the easy way out, just declare the method containing the oending function call as throwing Exceptions: public static void main(Strings[] args) throws Exception { FileInputStream in = new FileInputStream ( "filename" ); in.close(); } You can (ab)use exceptions as ways to pass messages between methods: public void doSomething throws Exception () { System.out.println("BARF!"); throw new Exception("oh no!"); } 7
public static void main(String[] args) { try { doSomething(); } catch (Exception e) { if (e.getMessage().equals("oh no!")) { System.out.println("it barfed as expected!"); } else { System.out.println("something mysterious!"); } } }
Regular Expressions
Regular Expressions are the best way to match a pattern in a string. Heres a simple example: Pattern p = Pattern.compile("a*b"); Matcher m = p.matcher("aaaaab"); boolean b = m.matches(); Pattern p contains the expression itself, and is immutable (the construction of the Matcher by the function performs all the work). In this case, its matching the star closure of a, and a single b, or in laymans terms, any number of as followed by a single b. Matcher m contains the resulting information about matching aaaaab to that machine, and boolean b actually tells us whether it matched or not (in this case, b is true). The above can also be expressed as: boolean b = Pattern.matches("a*b", "aaaaab"); However, that doesnt allow the pattern to be re-used for further matching. Substrings can be captured using parentheses in the expression, and the matched substrings busted out of the Matcher using the group function, which returns a (possibly empty) String if the substring was found, and null if it failed to match that part of the input. Calling group without any arguments gets the entire substring that matched.