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
00010
00011
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
00058
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
00085
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
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 }