00001 #ifndef PARENTITER_H
00002 #define PARENTITER_H
00003
00004 #include "array.h"
00005 #include "permutation.h"
00006 #include "arraysaccessor.h"
00007
00008 class ParentIter
00009 {
00010 public:
00011 ParentIter()
00012 {
00013
00014 }
00015
00016 ~ParentIter()
00017 {
00018
00019 }
00020
00021 ParentIter(const ParentIter& other)
00022 : size_(other.size_), fillerValues_(other.fillerValues_),
00023 reqValues_(other.reqValues_), reqGround_(other.reqGround_),
00024 fillerGround_(), firstTime_(other.firstTime_)
00025 {
00026 setupFillerIter();
00027 while (fillerGround_.getCombinationIndex() <
00028 other.fillerGround_.getCombinationIndex()) {
00029 fillerGround_.next();
00030 }
00031 }
00032
00033
00034 ParentIter(const Array<int>& required, const Array<int>* filler, int size)
00035 : size_(size), fillerValues_(*filler), reqValues_(required),
00036 reqGround_(), firstTime_(true)
00037 {
00038 Array<int> requiredWithSpaces(required);
00039 for (int i = required.size(); i < size; i++) {
00040 requiredWithSpaces.append(-2);
00041 }
00042 reqGround_.setValues(requiredWithSpaces);
00043 setupFillerIter();
00044 }
00045
00046 void reset()
00047 {
00048 reqGround_.reset();
00049 setupFillerIter();
00050 firstTime_ = true;
00051 }
00052
00053 bool hasNextGrounding() {
00054 return fillerGround_.hasNextCombination() || reqGround_.hasNext();
00055 }
00056
00057
00058 bool getNextGrounding(Array<int>& grounding)
00059 {
00060 grounding.clear();
00061 grounding.growToSize(size_);
00062
00063 if (firstTime_ || !fillerGround_.hasNextCombination()) {
00064 reqGround_.next();
00065 setupFillerIter();
00066 }
00067 firstTime_ = false;
00068
00069
00070 Array<int> fillerGrounding;
00071 fillerGround_.getNextCombination(fillerGrounding);
00072
00073
00074 int fillerIndex = 0;
00075 for (int i = 0; i < size_; i++) {
00076 if (reqGround_[i] < 0) {
00077 grounding[i] = fillerGrounding[fillerIndex++];
00078 } else {
00079 grounding[i] = reqGround_[i];
00080 }
00081 }
00082
00083 return hasNextGrounding();
00084 }
00085
00086
00087 protected:
00088 void setupFillerIter()
00089 {
00090
00091
00092
00093
00094
00095
00096
00097
00098 Array<int> seenSoFar;
00099 fillerGround_.deleteArraysAndClear();
00100 for (int i = 0; i < size_; i++) {
00101 if (reqGround_[i] >= 0) {
00102 seenSoFar.append(reqGround_[i]);
00103 } else {
00104 Array<int>* valList = new Array<int>;
00105 for (int fi = 0; fi < fillerValues_.size(); fi++) {
00106 bool seen = false;
00107 for (int si = 0; si < seenSoFar.size(); si++) {
00108 if (seenSoFar[si] == fillerValues_[fi]) {
00109 seen = true;
00110 break;
00111 }
00112 }
00113 if (!seen) {
00114 valList->append(fillerValues_[fi]);
00115 }
00116 }
00117
00118 fillerGround_.appendArray(valList);
00119 }
00120 }
00121 }
00122
00123
00124 private:
00125 int size_;
00126 Array<int> fillerValues_;
00127 Array<int> reqValues_;
00128 Permutation<int> reqGround_;
00129 ArraysAccessor<int> fillerGround_;
00130 bool firstTime_;
00131 };
00132
00133 #endif // ndef PARENTITER_H