// CSE 143, Winter 2010, Marty Stepp // This program uses recursive backtracking to print all permutations // (all possible arrangements of letters) of a given string. // // This file has an alternative implementation of the "subsets" problem // that uses lists rather than strings / chars to store choices. import java.util.*; public class Permutations { // turn on the DEBUG flag to see a bunch of helpful println statements // to watch the recursion trace private static final boolean DEBUG = false; public static void main(String[] args) { permute("MARTY"); System.out.println(); permute("JANE"); } // Prints all possible permutations of letters of the given string, // one per line. For example, permute("MARTY") prints MARTY, MATRY, // ATRMY, YARMT, etc. Uses backtracking to generate permutations. // Precondition: s is not null (throws NullPointerException if so) public static void permute(String s) { // represent the choices as a list of 1-letter strings List choices = new ArrayList(); for (int i = 0; i < s.length(); i++) { choices.add(s.substring(i, i + 1)); } // initially we have chosen zero letters List chosen = new ArrayList(); permute(choices, chosen); } // Recursive helper method for choosing letters and backtracking. // Additional 'chosen' parameter stores the letters we have picked so far. private static void permute(List choices, List chosen) { // uncomment the following line to see the recursive calls if (DEBUG) Recursion.println("PERMUTE(" + choices + ", " + chosen + ")"); if (choices.size() == 0) { // base case: all letters have been chosen. Print the chosen word if (DEBUG) Recursion.println("BASE CASE: " + chosen); for (String s : chosen) { System.out.print(s); } System.out.println(); } else { // for each possible choice i: // choose i. // explore the rest. // un-choose i. for (int i = 0; i < choices.size(); i++) { // [M, A, R, T, Y] [] // choose String myChoice = choices.remove(i); // "M" chosen.add(myChoice); // [A, R, T, Y] [M] if (DEBUG) Recursion.println("MAKE A CHOICE: " + myChoice); // explore the rest permute(choices, chosen); // un-choose chosen.remove(chosen.size() - 1); choices.add(i, myChoice); if (DEBUG) Recursion.println("UN-MAKE A CHOICE: " + myChoice); } } } }