00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef ASTL_NEIGHBOR_H
00023 #define ASTL_NEIGHBOR_H
00024
00025 #include <astl.h>
00026 #include <stack>
00027 #include <vector>
00028 #include <utility>
00029 #include <iostream>
00030 #include <cstring>
00031
00032 using namespace std;
00033
00034 namespace astl {
00035
00036 template <typename CharType>
00037 struct default_costs
00038 {
00039 int distance(const CharType &x, const CharType &y) const {
00040 return x == y ? 0 : 1000;
00041 }
00042
00043 template <typename RandomAccessIterator>
00044 int insertion(RandomAccessIterator last, RandomAccessIterator where, const CharType &c) const {
00045 return 1000;
00046 }
00047
00048 template <typename RandomAccessIterator>
00049 int deletion(RandomAccessIterator last, RandomAccessIterator where) const {
00050 return 1000;
00051 }
00052
00053 template <typename RandomAccessIterator>
00054 int deletion_suffix(RandomAccessIterator first, RandomAccessIterator last) const {
00055 return 1000;
00056 }
00057 };
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085 template <typename ForwardCursor, typename RandomAccessIterator,
00086
00087
00088 typename Costs = default_costs<typename ForwardCursor::char_type> >
00089 class neighbor_cursor : public forward_cursor_concept
00090 {
00091 protected:
00092 ForwardCursor x;
00093 RandomAccessIterator last;
00094 typedef vector<pair<RandomAccessIterator, int> > container;
00095 container d;
00096
00097 public:
00098 typedef neighbor_cursor self;
00099 typedef typename ForwardCursor::tag_type tag_type;
00100 typedef typename ForwardCursor::char_type char_type;
00101 typedef typename ForwardCursor::char_traits char_traits;
00102 typedef typename ForwardCursor::state_type state_type;
00103
00104 neighbor_cursor(const ForwardCursor& c, RandomAccessIterator i,
00105 RandomAccessIterator j, int dist)
00106 : x(c), last(j) {
00107 d.reserve(64);
00108 d.push_back(make_pair(i, dist));
00109 }
00110
00111 neighbor_cursor()
00112 { }
00113
00114 neighbor_cursor(const self &n)
00115 : x(n.x), last(n.last) {
00116 d.reserve(64);
00117 for(typename container::const_iterator i = n.d.begin();
00118 i != n.d.end(); ++i)
00119 if (i->second >= 0) d.push_back(*i);
00120 }
00121
00122 state_type src() const {
00123 return x.src();
00124 }
00125
00126 const ForwardCursor& cursor() const {
00127 return x;
00128 }
00129
00130 bool sink() const {
00131 return x.sink();
00132 }
00133
00134 state_type sink_state() const {
00135 return x.sink_state();
00136 }
00137
00138 bool forward(const char_type &a) {
00139 typename container::size_type i, j = d.size();
00140 bool ok = false;
00141
00142 if (x.forward(a))
00143 for(i = 0; i < j; ++i) {
00144
00145 int dist = d[i].second;
00146 for(RandomAccessIterator first = d[i].first;
00147 first != last && dist >= 0;
00148 dist -= Costs().deletion(last, first++)) {
00149
00150
00151 int delta = Costs().distance(*first, a);
00152 if (dist >= delta) {
00153 ok = true;
00154 d.push_back(make_pair(first + 1, dist - delta));
00155 }
00156 }
00157
00158
00159
00160 d[i].second -= Costs().insertion(last, d[i].first, a);
00161 ok = ok || d[i].second >= 0;
00162 }
00163 return ok;
00164 }
00165
00166 void forward() {
00167 typename container::size_type i, j = d.size();
00168
00169 for(i = 0; i < j; ++i) {
00170
00171 int dist = d[i].second;
00172 for(RandomAccessIterator first = d[i].first;
00173 first != last && dist >= 0;
00174 dist -= Costs().deletion(last, first++)) {
00175
00176
00177 int delta = Costs().distance(*first, x.letter());
00178 if (dist >= delta)
00179 d.push_back(make_pair(first + 1, dist - delta));
00180 }
00181
00182
00183 d[i].second -= Costs().insertion(last, d[i].first, x.letter());
00184 }
00185 x.forward();
00186 }
00187
00188 bool src_final() const {
00189 if (x.src_final())
00190 for(typename container::const_iterator i = d.begin(); i != d.end(); ++i)
00191
00192
00193 if (i->second >= Costs().deletion_suffix(i->first, last))
00194 return true;
00195 return false;
00196 }
00197
00198 tag_type src_tag() const {
00199 return x.src_tag();
00200 }
00201
00202 bool exists(const char_type &a) const {
00203 if (x.exists(a))
00204 for(typename container::const_iterator i = d.begin(); i != d.end(); ++i)
00205
00206 if (i->second >= Costs().insertion(last, i->first, a) ||
00207 (i->first != last
00208
00209
00210 && i->second >= Costs().distance(*i->first, a)))
00211 return true;
00212 return false;
00213 }
00214
00215 bool operator==(const self &s) const {
00216 return x == s.x;
00217 }
00218
00219 char_type letter() const {
00220 return x.letter();
00221 }
00222
00223 bool first() {
00224 if (x.first())
00225 do
00226 for(typename container::const_iterator i = d.begin();
00227 i != d.end(); ++i) {
00228 if (i->first != last) {
00229
00230
00231 if (i->second >= Costs().distance(*i->first, x.letter()))
00232 return true;
00233 }
00234
00235 if (i->second >= Costs().insertion(last, i->first, x.letter()))
00236 return true;
00237 }
00238 while (x.next());
00239 return false;
00240 }
00241
00242 bool next() {
00243 while (x.next())
00244 for(typename container::const_iterator i = d.begin(); i != d.end(); ++i) {
00245 if (i->first != last) {
00246
00247
00248 if (i->second >= Costs().distance(*i->first, x.letter()))
00249 return true;
00250 }
00251
00252 if (i->second >= Costs().insertion(last, i->first, x.letter()))
00253 return true;
00254 }
00255 return false;
00256 }
00257
00258 bool find(const char_type &a) {
00259 return true;
00260 }
00261
00262 state_type aim() const {
00263 return x.aim();
00264 }
00265
00266 bool aim_final() const {
00267 self tmp = *this;
00268 tmp.forward();
00269 return tmp.src_final();
00270 }
00271
00272 tag_type aim_tag() const {
00273 return x.aim_tag();
00274 }
00275
00276
00277 int distance() const {
00278 self tmp = *this;
00279 tmp.forward();
00280 typename container::const_iterator i, m = tmp.d.begin();
00281 for(i = tmp.d.begin() + 1; i != tmp.d.end(); ++i)
00282 if (i->second > m->second) m = i;
00283
00284 return m->second;
00285 }
00286
00287 };
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297 template <typename ForwardCursor, typename ForwardIterator, typename Distance>
00298 inline
00299 neighbor_cursor<ForwardCursor, ForwardIterator, Distance>
00300 neighborc(const ForwardCursor& x,
00301 ForwardIterator i, ForwardIterator j, int d, const Distance&) {
00302 return neighbor_cursor<ForwardCursor, ForwardIterator, Distance>
00303 (x, i, j, d);
00304 }
00305
00306 template <typename ForwardCursor>
00307 inline
00308 neighbor_cursor<ForwardCursor, const char*>
00309 neighborc(const ForwardCursor& x, const char *word, int d) {
00310 return neighbor_cursor<ForwardCursor, const char*>
00311 (x, word, word + strlen(word), d);
00312 }
00313
00314 }
00315
00316 #endif