00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066 #ifndef PERMUTATION_H
00067 #define PERMUTATION_H
00068 #include "array.h"
00069 #include "arraysaccessor.h"
00070
00071
00072
00073
00074
00075 template<typename Type>
00076 class Permutation
00077 {
00078 public:
00079 Permutation()
00080 : hasNext_(false)
00081 { }
00082
00083 Permutation(const Array<Type>& vals)
00084 { setValues(vals); }
00085
00086
00087 void setValues(const Array<Type>& vals)
00088 {
00089 values_ = vals;
00090
00091 perm_.clear();
00092 perm_.growToSize(values_.size());
00093 filled_.clear();
00094 filled_.growToSize(values_.size());
00095
00096
00097
00098 prevDuplicate_.clear();
00099 numLaterDuplicates_.clear();
00100 for (int i = 0; i < values_.size(); i++) {
00101 int prevDuplicate = -1;
00102 for (int j = 0; j < i; j++) {
00103 if (values_[j] == values_[i]) {
00104 prevDuplicate = j;
00105 numLaterDuplicates_[j]++;
00106 }
00107 }
00108 prevDuplicate_.append(prevDuplicate);
00109 numLaterDuplicates_.append(0);
00110 }
00111
00112 reset();
00113 }
00114
00115 void reset()
00116 {
00117 skips_.clear();
00118 skips_.growToSize(values_.size());
00119
00120
00121 for (int i = 0; i < skips_.size(); i++) {
00122 skips_[i] = 0;
00123 }
00124
00125 for (int i = 0; i < values_.size(); i++) {
00126 perm_[i] = values_[i];
00127 }
00128
00129
00130 hasNext_ = true;
00131 }
00132
00133 ~Permutation() { }
00134
00135 int size() {
00136 return values_.size();
00137 }
00138
00139 bool hasNext() {
00140 return hasNext_;
00141 }
00142
00143
00144 void next() {
00145
00146
00147 hasNext_ = false;
00148 for (int i = size() - 2; i >= 0; i--) {
00149 skips_[i]++;
00150 int numSkips = skips_[i];
00151
00152 int prevIndex = i;
00153 while (prevDuplicate_[prevIndex] >= 0) {
00154 numSkips += skips_[prevDuplicate_[prevIndex]];
00155 prevIndex = prevDuplicate_[prevIndex];
00156 }
00157 if (numSkips < size() - i - numLaterDuplicates_[i]) {
00158 hasNext_ = true;
00159 break;
00160 } else {
00161 skips_[i] = 0;
00162 }
00163 }
00164
00165
00166 for (int i = 0; i < size(); i++) {
00167 filled_[i] = false;
00168 }
00169
00170 for (int i = 0; i < size(); i++) {
00171 int numSkips = skips_[i];
00172 if (prevDuplicate_[i] >= 0) {
00173 numSkips += skips_[prevDuplicate_[i]];
00174 }
00175 int currIndex = 0;
00176 while (numSkips > 0 || filled_[currIndex]) {
00177 if (!filled_[currIndex]) {
00178 numSkips--;
00179 }
00180 currIndex++;
00181 assert (currIndex < size());
00182 }
00183 perm_[currIndex] = values_[i];
00184 filled_[currIndex] = true;
00185 }
00186 }
00187
00188 Type operator[](int idx) {
00189 return perm_[idx];
00190 }
00191
00192
00193 private:
00194 bool hasNext_;
00195 Array<int> skips_;
00196 Array<Type> values_;
00197 Array<bool> filled_;
00198 Array<Type> perm_;
00199 Array<int> prevDuplicate_;
00200 Array<int> numLaterDuplicates_;
00201 };
00202 #endif // ndef PERMUTATION_H