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;}
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
>=
.)
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;}
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;}
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