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;}
```

- 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;}`

Last modified 6 December 2007