combinatory.h

00001 /*
00002  * ASTL - the Automaton Standard Template Library.
00003  * C++ generic components for Finite State Automata handling.
00004  * Copyright (C) 2000-2003 Vincent Le Maout (vincent.lemaout@chello.fr).
00005  * 
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2.1 of the License, or (at your option) any later version.
00010  * 
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  * 
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this library; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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 // A combination_cursor simulates a DFA whose language is the combinations
00032 // with p intergers out of n (C(n,p)).
00033 // Example: combination_cursor(3, 2) recognizes:
00034 //               1 2
00035 //               2 1
00036 //               1 3
00037 //               3 1
00038 //               2 3
00039 //               3 2
00040 // Constructor:
00041 // 1. n, p
00042 
00043 class combination_cursor : public forward_cursor_concept
00044 {
00045 protected:
00046   pair<std::vector<bool>, int> q;
00047   int current; // current letter
00048   // q.second is p - q.first's count of 1
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(); // move to sink state
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 // Helper functions:
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 } // namespace astl
00163 
00164 #endif // ASTL_COMBINATORY_H
00165         
00166     
00167          
00168     
00169          

Generated on Sun Mar 8 02:41:30 2009 for ASTL by  doxygen 1.5.7.1