00001 #pragma ident "$Id: Combinations.hpp 3140 2012-06-18 15:03:02Z susancummins $"
00002
00008 #ifndef COMBINATIONS_INCLUDE
00009 #define COMBINATIONS_INCLUDE
00010
00011 namespace gpstk {
00012
00013 #include "Exception.hpp"
00014
00021 class Combinations {
00022 public:
00024 Combinations(void) throw()
00025 {
00026 nc = n = k = 0;
00027 Index = std::vector<int>(0);
00028 }
00029
00032 Combinations(int N, int K) throw(Exception)
00033 { init(N,K); }
00034
00036 Combinations(const Combinations& right)
00037 throw()
00038 {
00039 *this = right;
00040 }
00041
00043 Combinations& operator=(const Combinations& right) throw()
00044 {
00045 init(right.n,right.k);
00046 nc = right.nc;
00047 for(int j=0; j<k; j++) Index[j] = right.Index[j];
00048 return *this;
00049 }
00050
00053 int Next(void) throw() {
00054 if(k < 1) return -1;
00055 if(Increment(k-1) != -1) return ++nc;
00056 return -1;
00057 }
00058
00061 int Selection(int j) throw()
00062 {
00063 if(j < 0 || j >= k) return -1;
00064 return Index[j];
00065 }
00066
00069 bool isSelected(int j) throw()
00070 {
00071 for(int i=0; i<k; i++)
00072 if(Index[i] == j) return true;
00073 return false;
00074 }
00075
00076 private:
00077
00080 void init(int N, int K) throw(Exception)
00081 {
00082 if(K > N || N < 0 || K < 0) {
00083 Exception e("Combinations(n,k) must have k <= n, with n,k >= 0");
00084 GPSTK_THROW(e);
00085 }
00086
00087 Index = std::vector<int>(K);
00088 nc = 0;
00089 k = K;
00090 n = N;
00091 for(int j=0; j<k; j++)
00092 Index[j] = j;
00093 }
00094
00096 int Increment(int j) throw()
00097 {
00098 if(Index[j] < n-k+j) {
00099 Index[j]++;
00100 for(int m=j+1; m<k; m++)
00101 Index[m]=Index[m-1]+1;
00102 return 0;
00103 }
00104
00105 if(j-1 < 0) return -1;
00106
00107 return Increment(j-1);
00108 }
00109
00110
00111 int nc;
00112 int k,n;
00113 std::vector<int> Index;
00114
00115
00116 };
00117
00118 }
00119
00120 #endif // COMBINATIONS_INCLUDE