00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef ASTL_COMBINATORY_H
00023 #define ASTL_COMBINATORY_H
00024
00025 #include <astl.h>
00026 #include <vector>
00027 #include <string>
00028
00029 namespace astl {
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 class combination_cursor : public forward_cursor_concept
00044 {
00045 protected:
00046 pair<std::vector<bool>, int> q;
00047 int current;
00048
00049
00050 public:
00051 typedef combination_cursor self;
00052 typedef empty tag_type;
00053 typedef pair<std::vector<bool>, int> state_type;
00054 typedef int char_type;
00055
00056 #if (__GNUG__ && __GNUG__ < 3)
00057 typedef string_char_traits<int> char_traits;
00058 #else
00059 typedef std::char_traits<int> char_traits;
00060 #endif
00061
00062 combination_cursor()
00063 { }
00064
00065 combination_cursor(int n, int p)
00066 : q(vector<bool>(n, false), p), current(-1)
00067 { }
00068
00069 state_type src() const { return q; }
00070
00071 state_type aim() const {
00072 state_type tmp(q.first, q.second - 1);
00073 tmp.first[current] = true;
00074 return tmp;
00075 }
00076
00077 bool sink() const { return q.first.empty(); }
00078
00079 state_type sink_state() const {
00080 return state_type(vector<bool>(), -1);
00081 }
00082
00083 bool exists(int i) const { return q.second > 0 && !q.first[i - 1]; }
00084
00085 void forward() {
00086 --q.second;
00087 q.first[current] = true;
00088 }
00089
00090 bool forward(int letter) {
00091 if (q.second-- > 0 && q.first[letter - 1] == false) {
00092 q.first[letter - 1] = true;
00093 return true;
00094 }
00095 q.first.clear();
00096 q.second = -1;
00097 return false;
00098 }
00099
00100 bool first() {
00101 if (q.second > 0)
00102 for(vector<bool>::const_iterator i = q.first.begin();
00103 i != q.first.end(); ++i)
00104 if (*i == false) {
00105 current = i - q.first.begin();
00106 return true;
00107 }
00108 current = -1;
00109 return false;
00110 }
00111
00112 bool next() {
00113 for(vector<bool>::const_iterator i = q.first.begin() + current + 1;
00114 i != q.first.end(); ++i)
00115 if (*i == false) {
00116 current = i - q.first.begin();
00117 return true;
00118 }
00119 current = -1;
00120 return false;
00121 }
00122
00123 int letter() const { return current + 1; }
00124
00125 tag_type src_tag() const { return tag_type(); }
00126 tag_type aim_tag() const { return tag_type(); }
00127
00128 bool src_final() const { return q.second == 0; }
00129
00130 bool aim_final() const { return q.second == 1; }
00131
00132 bool operator==(const self &x) const {
00133 return q == x.q && current == x.current;
00134 }
00135
00136 bool find(int letter) {
00137 if (q.second > 0 && q.first[letter - 1] == false) {
00138 current = letter - 1;
00139 return true;
00140 }
00141 current = -1;
00142 return false;
00143 }
00144
00145 self& operator=(const state_type &p) {
00146 q = p;
00147 return *this;
00148 }
00149 };
00150
00151
00152 inline
00153 combination_cursor permutationc(int n) {
00154 return combination_cursor(n, n);
00155 }
00156
00157 inline
00158 combination_cursor combinationc(int n, int p) {
00159 return combination_cursor(n, p);
00160 }
00161
00162 }
00163
00164 #endif // ASTL_COMBINATORY_H
00165
00166
00167
00168
00169