CMS 3D CMS Logo

combination.h
Go to the documentation of this file.
1 //=======================================================
2 // combination.h
3 // Description : Template class to find combinations
4 //=======================================================
5 // Copyright 2003 - 2006 Wong Shao Voon
6 // No warranty, implied or expressed, is included.
7 // Author is not liable for any type of loss through
8 // the use of this source code. Use it at your own risk!
9 //=======================================================
10 
11 #ifndef __COMBINATION_H__
12 #define __COMBINATION_H__
13 
14 namespace stdcomb {
15 
16  // Non recursive template function
17  template <class BidIt>
18 
19  inline bool next_combination(BidIt n_begin, BidIt n_end, BidIt r_begin, BidIt r_end) {
20  bool boolmarked = false;
21  BidIt r_marked;
22 
23  BidIt n_it1 = n_end;
24  --n_it1;
25 
26  BidIt tmp_r_end = r_end;
27  --tmp_r_end;
28 
29  for (BidIt r_it1 = tmp_r_end; r_it1 != r_begin || r_it1 == r_begin; --r_it1, --n_it1) {
30  if (*r_it1 == *n_it1) {
31  if (r_it1 != r_begin) //to ensure not at the start of r sequence
32  {
33  boolmarked = true;
34  r_marked = (--r_it1);
35  ++r_it1; //add it back again
36  continue;
37  } else // it means it is at the start the sequence, so return false
38  return false;
39  } else //if(*r_it1!=*n_it1 )
40  {
41  //marked code
42  if (boolmarked == true) {
43  //for loop to find which marked is in the first sequence
44  BidIt n_marked; //mark in first sequence
45  for (BidIt n_it2 = n_begin; n_it2 != n_end; ++n_it2)
46  if (*r_marked == *n_it2) {
47  n_marked = n_it2;
48  break;
49  }
50 
51  BidIt n_it3 = ++n_marked;
52  for (BidIt r_it2 = r_marked; r_it2 != r_end; ++r_it2, ++n_it3) {
53  *r_it2 = *n_it3;
54  }
55  return true;
56  }
57  for (BidIt n_it4 = n_begin; n_it4 != n_end; ++n_it4)
58  if (*r_it1 == *n_it4) {
59  *r_it1 = *(++n_it4);
60  return true;
61  }
62  }
63  }
64 
65  return true; //will never reach here
66  }
67 
68  // Non recursive template function with Pred
69  template <class BidIt, class Prediate>
70 
71  inline bool next_combination(BidIt n_begin, BidIt n_end, BidIt r_begin, BidIt r_end, Prediate Equal) {
72  bool boolmarked = false;
73  BidIt r_marked;
74 
75  BidIt n_it1 = n_end;
76  --n_it1;
77 
78  BidIt tmp_r_end = r_end;
79  --tmp_r_end;
80 
81  for (BidIt r_it1 = tmp_r_end; r_it1 != r_begin || r_it1 == r_begin; --r_it1, --n_it1) {
82  if (Equal(*r_it1, *n_it1)) {
83  if (r_it1 != r_begin) //to ensure not at the start of r sequence
84  {
85  boolmarked = true;
86  r_marked = (--r_it1);
87  ++r_it1; //add it back again
88  continue;
89  } else // it means it is at the start the sequence, so return false
90  return false;
91  } else //if(*r_it1!=*n_it1 )
92  {
93  //marked code
94  if (boolmarked == true) {
95  //for loop to find which marked is in the first sequence
96  BidIt n_marked; //mark in first sequence
97  for (BidIt n_it2 = n_begin; n_it2 != n_end; ++n_it2)
98  if (Equal(*r_marked, *n_it2)) {
99  n_marked = n_it2;
100  break;
101  }
102 
103  BidIt n_it3 = ++n_marked;
104  for (BidIt r_it2 = r_marked; r_it2 != r_end; ++r_it2, ++n_it3) {
105  *r_it2 = *n_it3;
106  }
107  return true;
108  }
109  for (BidIt n_it4 = n_begin; n_it4 != n_end; ++n_it4)
110  if (Equal(*r_it1, *n_it4)) {
111  *r_it1 = *(++n_it4);
112  return true;
113  }
114  }
115  }
116 
117  return true; //will never reach here
118  }
119 
120  // Non recursive template function
121  template <class BidIt>
122 
123  inline bool prev_combination(BidIt n_begin, BidIt n_end, BidIt r_begin, BidIt r_end) {
124  BidIt marked; //for r
125  BidIt r_marked;
126  BidIt n_marked;
127 
128  BidIt tmp_n_end = n_end;
129  --tmp_n_end;
130 
131  BidIt r_it1 = r_end;
132  --r_it1;
133 
134  for (BidIt n_it1 = tmp_n_end; n_it1 != n_begin || n_it1 == n_begin; --n_it1) {
135  if (*r_it1 == *n_it1) {
136  r_marked = r_it1;
137  n_marked = n_it1;
138  break;
139  }
140  }
141 
142  BidIt n_it2 = n_marked;
143 
144  BidIt tmp_r_end = r_end;
145  --tmp_r_end;
146 
147  for (BidIt r_it2 = r_marked; r_it2 != r_begin || r_it2 == r_begin; --r_it2, --n_it2) {
148  if (*r_it2 == *n_it2) {
149  if (r_it2 == r_begin && !(*r_it2 == *n_begin)) {
150  for (BidIt n_it3 = n_begin; n_it3 != n_end; ++n_it3) {
151  if (*r_it2 == *n_it3) {
152  marked = r_it2;
153  *r_it2 = *(--n_it3);
154 
155  BidIt n_it4 = n_end;
156  --n_it4;
157  for (BidIt r_it3 = tmp_r_end; (r_it3 != r_begin || r_it3 == r_begin) && r_it3 != marked;
158  --r_it3, --n_it4) {
159  *r_it3 = *n_it4;
160  }
161  return true;
162  }
163  }
164  } else if (r_it2 == r_begin && *r_it2 == *n_begin) {
165  return false; //no more previous combination;
166  }
167  } else //if(*r_it2!=*n_it2 )
168  {
169  ++r_it2;
170  marked = r_it2;
171  for (BidIt n_it5 = n_begin; n_it5 != n_end; ++n_it5) {
172  if (*r_it2 == *n_it5) {
173  *r_it2 = *(--n_it5);
174 
175  BidIt n_it6 = n_end;
176  --n_it6;
177  for (BidIt r_it4 = tmp_r_end; (r_it4 != r_begin || r_it4 == r_begin) && r_it4 != marked; --r_it4, --n_it6) {
178  *r_it4 = *n_it6;
179  }
180  return true;
181  }
182  }
183  }
184  }
185  return false; //Will never reach here, unless error
186  }
187 
188  // Non recursive template function with Pred
189  template <class BidIt, class Prediate>
190 
191  inline bool prev_combination(BidIt n_begin, BidIt n_end, BidIt r_begin, BidIt r_end, Prediate Equal) {
192  BidIt marked; //for r
193  BidIt r_marked;
194  BidIt n_marked;
195 
196  BidIt tmp_n_end = n_end;
197  --tmp_n_end;
198 
199  BidIt r_it1 = r_end;
200  --r_it1;
201 
202  for (BidIt n_it1 = tmp_n_end; n_it1 != n_begin || n_it1 == n_begin; --n_it1) {
203  if (Equal(*r_it1, *n_it1)) {
204  r_marked = r_it1;
205  n_marked = n_it1;
206  break;
207  }
208  }
209 
210  BidIt n_it2 = n_marked;
211 
212  BidIt tmp_r_end = r_end;
213  --tmp_r_end;
214 
215  for (BidIt r_it2 = r_marked; r_it2 != r_begin || r_it2 == r_begin; --r_it2, --n_it2) {
216  if (Equal(*r_it2, *n_it2)) {
217  if (r_it2 == r_begin && !Equal(*r_it2, *n_begin)) {
218  for (BidIt n_it3 = n_begin; n_it3 != n_end; ++n_it3) {
219  if (Equal(*r_it2, *n_it3)) {
220  marked = r_it2;
221  *r_it2 = *(--n_it3);
222 
223  BidIt n_it4 = n_end;
224  --n_it4;
225  for (BidIt r_it3 = tmp_r_end; (r_it3 != r_begin || r_it3 == r_begin) && r_it3 != marked;
226  --r_it3, --n_it4) {
227  *r_it3 = *n_it4;
228  }
229  return true;
230  }
231  }
232  } else if (r_it2 == r_begin && Equal(*r_it2, *n_begin)) {
233  return false; //no more previous combination;
234  }
235  } else //if(*r_it2!=*n_it2 )
236  {
237  ++r_it2;
238  marked = r_it2;
239  for (BidIt n_it5 = n_begin; n_it5 != n_end; ++n_it5) {
240  if (Equal(*r_it2, *n_it5)) {
241  *r_it2 = *(--n_it5);
242 
243  BidIt n_it6 = n_end;
244  --n_it6;
245  for (BidIt r_it4 = tmp_r_end; (r_it4 != r_begin || r_it4 == r_begin) && r_it4 != marked; --r_it4, --n_it6) {
246  *r_it4 = *n_it6;
247  }
248  return true;
249  }
250  }
251  }
252  }
253  return false; //Will never reach here, unless error
254  }
255 
256  // Recursive template function
257  template <class RanIt, class Func>
258 
260  RanIt nbegin, RanIt nend, int n_column, RanIt rbegin, RanIt rend, int r_column, int loop, Func func) {
261  int r_size = rend - rbegin;
262 
263  int localloop = loop;
264  int local_n_column = n_column;
265 
266  //A different combination is out
267  if (r_column > (r_size - 1)) {
268  func(rbegin, rend);
269  return;
270  }
272 
273  for (int i = 0; i <= loop; ++i) {
274  RanIt it1 = rbegin;
275  for (int cnt = 0; cnt < r_column; ++cnt) {
276  ++it1;
277  }
278 
279  RanIt it2 = nbegin;
280  for (int cnt2 = 0; cnt2 < n_column + i; ++cnt2) {
281  ++it2;
282  }
283 
284  *it1 = *it2;
285 
286  ++local_n_column;
287 
288  recursive_combination(nbegin, nend, local_n_column, rbegin, rend, r_column + 1, localloop, func);
289  --localloop;
290  }
291  }
292 
293 } // namespace stdcomb
294 
295 #endif
void recursive_combination(RanIt nbegin, RanIt nend, int n_column, RanIt rbegin, RanIt rend, int r_column, int loop, Func func)
Definition: combination.h:259
bool prev_combination(BidIt n_begin, BidIt n_end, BidIt r_begin, BidIt r_end)
Definition: combination.h:123
bool next_combination(BidIt n_begin, BidIt n_end, BidIt r_begin, BidIt r_end)
Definition: combination.h:19