ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE-2.0/test/utils/next_combination.hpp
Revision: 1666
Committed: Thu Oct 28 15:02:54 2004 UTC (19 years, 8 months ago) by tim
File size: 4100 byte(s)
Log Message:
STL Compatible combination sequence generator

File Contents

# Content
1 /*
2 * Copyright (C) 2000-2004 Object Oriented Parallel Simulation Engine (OOPSE) project
3 *
4 * Contact: oopse@oopse.org
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public License
8 * as published by the Free Software Foundation; either version 2.1
9 * of the License, or (at your option) any later version.
10 * All we ask is that proper credit is given for our work, which includes
11 * - but is not limited to - adding the above copyright notice to the beginning
12 * of your source code files, and to any copyright notice that you may distribute
13 * with programs based on this work.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 *
24 */
25
26 /**
27 * @file GenerateCombination.hpp
28 * @author tlin
29 * @date 10/27/2004
30 * @version 1.0
31 */
32
33 #ifndef UTILS_NEXT_COMBINATION_HPP
34 #define UTILS_NEXT_COMBINATION_HPP
35
36 #include <vector>
37 #include <iterator>
38
39 namespace oopse {
40
41 /**
42 * STL next_permuationtation like combination sequence generator
43 *
44 * <p> Preconditions: </p>
45 *
46 */
47 template<class BidirectionalIterator, template<typename ELEM, typename = std::allocator<ELEM> > class IteratorContainer = std::vector>
48 bool next_permutation(IteratorContainer<BidirectionalIterator>& iterContainer, BidirectionalIterator first, BidirectionalIterator last) {
49 if (first == last) {
50 return false;
51 }
52
53 BidirectionalIterator endIter = --last;
54 typename IteratorContainer::iterator i = iterContainer.end();
55
56 if (iterContainer.empty()) {
57 //if sequence is empty, we insert the first iterator
58 iterContainer.insert(iterContainer.end(), first);
59 return true;
60 } else if (*(--i) != endIter){
61 //if the last iterator in iterContainer does not reaches the end, just increment it
62 *i++;
63 return true;
64 } else {// the last iterator in iterContainer does not reaches the end
65
66 //starts at the end of the sequence and works its way towards the front, looking for two
67 //consecutive members of the sequence where the difference between them is greater
68 //than one. For example , if the sequence contains 1, 5, 8, 9 (total number is 10, begin
69 //index is 0, therefore 9 is the end index, and the current size is 4). At the end of while
70 //loop, j will point to 5, and i will point to 8, next combination should be 1, 6, 7, 8.
71 //If j is less than zero, it means it already reaches the last combination of current size.
72 //For instance, sequence may contain 6, 7, 8, 9 at this time, we need to increase the size
73 // of combination to 5
74 typename IteratorContainer::iterator j = i;
75 j--;
76 while( j >= first && *i == *j + 1){
77 i--;
78 j--;
79 };
80
81 BidirectionalIterator biDirIter;
82 if (j < first) { //reaches the last combination of current size
83
84 if (last - first == iterContainer.size()) {
85 //if the current size equals to total number, done
86 return false;
87 } else {
88
89 //push the first currentSize+1 element into sequence
90 for(i = iterContainer.begin(), biDirIter= first; i != iterContainer.end(); ++i, ++biDirIter) {
91 *i = j;
92 }
93 iterContainer.insert(iterContainer.end(), ++biDirIter);
94
95 return true;
96 }
97 } else {
98 ++(*j);
99 for(bidirIter = *j; i != iterContainer.size(); ++i, ++biDirIter) {
100 *i = biDirIter;
101 }
102 return true;
103 }
104 }
105 }
106
107 #endif //UTILS_NEXT_COMBINATION_HPP
108