need good permutaion generator in C

Dave Gillespie daveg at near.cs.caltech.edu
Mon Oct 22 20:48:28 AEST 1990


>>>>> On 19 Oct 90 15:15:37 GMT, grimlok at hubcap.clemson.edu (Mike Percy) said:

> I'm looking for an iterative (not recursive like the ones I already
> know) permutation routine.

Dijkstra's _A Discipline of Programming_ has a nice little next-permutation
algorithm.  Given an input permutation in an array, it changes it to the
lexicographically next permutation.  So you start with "1 2 3" and repeat
the algorithm until you get to "3 2 1".

Dijkstra invents his own language for use in this book, but I'll be brave
and do an off-the-cuff translation to C.  (This will be untested, but
then Dijkstra proudly states in the introduction that his programs were
published untested since they were derived by such rigorous methods.
Hey, guys, let's start a flame war on the merits of that remark!)


#define SWAP(x,y) { int t = x; x = y; y = t; }

/* Increment the permutation in perm[0] ... perm[n-1]. */
void next_perm(int perm[], int n)
{
  int i = n - 2;   /* Index of leftmost element which needs to change. */
  int j = n - 1;   /* Index of element perm[i] will change to. */

  /* Only the tail of elements in decreasing order must change. */
  while (perm[i] >= perm[i+1]) i--;

  /* perm[i] inherits the next-higher value from the tail. */
  while (perm[j] <= perm[i]) j--;

  /* Swap that into position.  Rest of tail is still decreasing. */
  SWAP(perm[i], perm[j]);

  /* Now reverse the tail end-for-end to get increasing order. */
  j = n;
  while (++i < --j)
    SWAP(perm[i], perm[j]);
}


I always thought this was a fine example of the beauty of good
algorithms.  A place for everything, everything in its place.

You can get the program to test if you have reached the last
permutation automatically by changing the first while loop thusly:

  while (perm[i] >= perm[i+1])
    if (--i < 0)
      return DONE;   /* Input was already the last permutation */

								-- Dave
--
Dave Gillespie
  256-80 Caltech Pasadena CA USA 91125
  daveg at csvax.cs.caltech.edu, ...!cit-vax!daveg



More information about the Comp.lang.c mailing list