# CMPSCI 250 Discussion #10: Generating Permutations and Combinations

#### 5 December 2007

The exercise was to write several additional methods for the following Java class. Throughout, a "sequence" is a sequence of k elements of the set {1,...,n}, a "permutation" is a sequence that does not have two or more equal elements, and a "set" is a permutation whose elements occur in order. Here is the code I provided, with one addition -- a copy constructor that has the same effect as a "clone" method:

``````
public class Sequence
{// Stores sequence of k elements from set of naturals from 1 to n
static int k,n; // class variables, fixed for the problem
int [] values = new int[k];

public Sequence()
{// Constructs first sequence in order, all ones
for (int i=0; i < k; i++)
values[i] = 1;}

public Sequence(Sequence s)
{// Copy Constructor
this();
for (int i=0; i < k; i++)
values[i] = s.values[i];}

public static Sequence firstSet();
{// Returns sequence [1,...,k]
Sequence s = new Sequence();
for (int i=0; i < k; i++)
s.values[i] = i+1;
return s;}

public String toString ()
{// Returns String describing calling sequence
String w = "";
if (k > 0) w += values[0];
for (int i=1; i < k; i++)
w += " " + values[i];
return w;}

public void listSequences
{// Prints all sequences in order
Sequence s = new Sequence();
while (!isLast()) {
System.out.println (s);
s = s.next();}
System.out.println(s);}

public void listSets()
Sequence s = firstSet();
while (!isLastSet()) {
System.out.println(s);
s = s.nextSet();}
System.out.println(s);}

public boolean isPerm()
{// returns whether this Sequence is a permutation
for (int i=0; i < k; i++)
for (int j = i+1; j < k; j++)
if (values[i] == values[j]) return false;
return true;}

``````

### Writing Exercises (solutions in blue)

• Write a boolean method `isSet` for the `Sequence` that determines whether the calling sequence is a sorted permutation. Use `isPerm` above as a model, but don't call `isPerm`.

``````
public boolean isSet()
{// Is this a sorted permutation, i.e., a set?
for (int i=0; i < k-1; i++)
if (values[i] >= values[j]) return false;
return true;}
``````

(Someone cleverly noticed that you can get a correct, though less efficient, version of `isSet` by taking `isPerm` and just replacing the `==` in the `if` statement with `>=`.)

• Write boolean methods `isLast`, `isLastSet`, and `isLastPerm` to determine whether the calling sequence is the last of the specified type in lexicographic order. If it is not of the required type, return `false` rather than throw an exception.

``````
public boolean isLast()
{// is this the last sequence, [n,...,n]?
for (int i=0; i < k; i++)
if (values[i] != n) return false;
return true;}

public boolean isLastSet()
{// is this the last set, [n-k+1,...,n]?
for (int i=0; i < k; i++)
if (values[i] != n-k+1+i) return false;
return true;}

public boolean isLastPerm()
{// is this the last permutation, [n,...,n-k+1]?
for (int i=0; i < k; i++)
if (values[i] != n-i) return false;
return true;}
``````
• Write a method `next` that returns the next `Sequence` (of the same length) in lexicographic order after the calling sequence. If the calling sequence is the last one in the order, throw an exception.

``````
public Sequence next()
{// returns next sequence after this in lexicographic order
if (isLast()) throw new Exception ("next called from last sequence");
Sequence t = new Sequence(this);
int index = k-1;
while (values[index] == n) {
t.values[index] = 1;
index--;}
t.values[index]++;
return t;}
``````
• Write a method `nextSet` that, if the calling sequence is a set, returns a `Sequence` that is the next set of that size in lexicographic order. Throw an exception if there is no such set or if the calling sequence is not a set.

``````
public Sequence nextSet()
{// returns next set after this in lexicographic order, if this is a set
if (!isSet()) throw new Exception ("nextSet called from non-set");
if (isLastSet()) throw new Exception ("nextSet called from last set");
Sequence t = new Sequence(this);
int index = k-1;
while (values[index] == n-k+1+index)
index--;
t.values[index]++;
for (int j = index+1; j < k; j++)
t.values[j] = t.values[j-1] + 1;
return t;}
``````