Main Page | Class List | File List | Class Members | File Members

comb.c

Go to the documentation of this file.
00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include "comb.h"
00004 #include "error.h"
00005 #include "standard.h"
00006 
00007 combinations *new_combinations(int numbers[], int n, int r)
00008      /*
00009       * Makes a combinations record which can be used in successive calls
00010       * to next_combination() in order to go through all the combinations
00011       * of length r from a set of numbers of length n. 
00012       */
00013 {
00014   int i;
00015   combinations *bob = (combinations *) malloc(sizeof(combinations));
00016   if (bob != NULL) {
00017     bob->n = n;
00018     bob->r = r;
00019     bob->numbers = (int *) malloc(n * sizeof(int));
00020 
00021     if ((bob->numbers==NULL) && (n>0))
00022       error("new_combinations", "malloc failed..");
00023     else {
00024       for (i=0; i<n; i++)
00025         bob->numbers[i] = numbers[i];
00026     }
00027 
00028     bob->curr = (int *) malloc(r * sizeof(int));
00029     bob->next = (int *) malloc(r * sizeof(int)); 
00030     if (((bob->curr == NULL) || (bob->next == NULL)) && (r > 0)) {
00031       error("new_combinations", "malloc failed...");
00032     }
00033     else {
00034       for (i=0; i<r; i++)
00035         bob->next[i] = i;
00036     }
00037     
00038     bob->x = (int *) malloc(r * sizeof(int));
00039     if ((bob->x == NULL)&&(r>0)) {
00040       error("new_combinations", "malloc failed....");
00041     }
00042     else {
00043       for (i=0; i<r; i++) 
00044         bob->x[i] = bob->numbers[i];
00045     }
00046     bob->last = 0;
00047   }
00048   else {
00049     error("new_combinations", "malloc failed.");
00050   }
00051   return (bob);
00052 }
00053 
00054 
00055 static int incr(int *x, int n, int r)
00056      /*
00057       * Increments combination pointers.  
00058       * Returns 0 iff the input was the last combination. 
00059       */
00060 {
00061   int tmp;
00062 
00063   if (r <= 0) {
00064     return (0);
00065   }
00066   else  if (r == 1) {
00067     return (++x[0] < n);
00068   } 
00069   else {
00070     if (++x[r-1] >= n) {
00071       tmp = incr(x, n-1, r-1);
00072       x[r-1] = x[r-2]+1;
00073       return(tmp);
00074     }
00075     else {
00076       return(1);
00077     }
00078   }
00079 }
00080 
00081 
00082 int *next_combination(combinations *bob)
00083      /*
00084       * Returns a pointer to an array of integers describing the next 
00085       * combination of the array of numbers stored in (bob).  
00086       */
00087 {
00088   int *this = NULL;
00089   int i;
00090   if (bob != NULL) {
00091     if (!bob->last) {
00092       for (i=0; i<bob->r; i++) {
00093         bob->curr[i] = bob->next[i];
00094         bob->x[i] = bob->numbers[bob->curr[i]];
00095       }
00096       this = bob->x;
00097       if (!incr(bob->next, bob->n, bob->r))
00098         bob->last = 1;
00099     }
00100   } 
00101   else {
00102     warn("next_combination", "invalid combinations.");
00103   }
00104   return (this);
00105 }
00106 
00107 
00108 void close_combinations(combinations *bob)
00109      /*
00110       * Frees some memory.
00111       */
00112 {
00113   if (bob != NULL) {
00114     if (bob->numbers != NULL)
00115       free(bob->numbers);
00116     if (bob->curr != NULL)
00117       free(bob->curr);
00118     if (bob->next != NULL)
00119       free(bob->next);
00120     if (bob->x != NULL)
00121       free(bob->x);
00122     free(bob);
00123   }
00124 }

Generated on Sun Jul 16 16:27:45 2006 by  doxygen 1.3.9.1