所以,假设我们想在所有偶数正数上迭代某个函数,该正数小于或等于100.我们可以这样做:
vector<int> v;
for (int i=0; i<=100; i+=2) v.push_back(i);
for_each(v.begin(), v.end(), ourFunction);
其他更简单的方法是:
for (int i=0; i<=100; i+=2) ourFunction(i);
现在,假设我们想要迭代一个更复杂的集合。例如,回文数(基数10)小于1000000.我们可以这样做:
inline int tenTo(int power) { int n= 1; for(int i=0; i<power; i++) n*=10; return n; }
vector<int> getPalindromial(int digits, bool firstCall = true,vector<int> &fakePalindromial = vector<int>()) {
if (digits == 1) {
// Base Case 1
vector<int> v;
fakePalindromial.push_back(0);
for (int i=1; i<=9; i++) {
v.push_back(i);
fakePalindromial.push_back(i);
}
return v;
} else if (digits == 2) {
// Base Case 2
vector<int> v;
fakePalindromial.push_back(0);
for (int i=11; i<=99; i += 11) {
v.push_back(i);
fakePalindromial.push_back(i);
}
return v;
} else {
if (firstCall) {
// If this is the first call, we built all the odd lenght numbers and the even length numbers and then we join them and return.
vector<int> v1 = getPalindromial(digits,false);
vector<int> v2 = getPalindromial(digits-1,false);
v1.insert(v1.end(), v2.begin(), v2.end());
return v1;
}
/* Recursive case:
* For each palindromical number with 2 less digits, we add each digit at start and at the end
*/
vector<int> v = getPalindromial(digits-2,false,fakePalindromial);
const int size = fakePalindromial.size();
for (int i=0; i<size; i++) {
const int n = fakePalindromial[i];
int nDigits = 1;
for (int i=0; i< digits-2; i++) {
nDigits *= 10;
}
/* Numbers with leading 0 are not really palindromical, but will be usefull to the functions building higher
* numbers ( 010 is not palindromical, but it is usefull for building 50105)
*/
int digit = 0;
fakePalindromial.push_back(10*(nDigits*digit + n) + digit);
for (int digit=1; digit<=9; digit++) {
v.push_back(10*(nDigits*digit + n) + digit);
fakePalindromial.push_back(10*(nDigits*digit + n) + digit);
}
}
// Clean the palindromical numbers that we have used
for (int i=0; i<size; i++) {
fakePalindromial.erase(fakePalindromial.begin());
}
return v;
}
}
然后:
vector<int> v = getPalindromial(6);
for_each(v.begin(), v.end(), ourFunction);
如何在不生成洞穴集合的情况下实现相同的目标,然后对其进行迭代?
(注意:getPalindromial函数可能更简单,它是以这种方式制作的,所以它更复杂)
答案 0 :(得分:3)
将您的集合表示为生成器对象,其方法是前进到下一个逻辑元素,获取当前元素,以及将当前元素与 end 元素进行比较。
然后使用Boost Iterator Facade,http://www.boost.org/doc/libs/1_54_0/libs/iterator/doc/index.html#iterator-facade-and-adaptor(参见他们的示例)或实现自己的:http://www.cplusplus.com/reference/iterator/iterator/
答案 1 :(得分:1)
为此,我会尝试使用定制迭代器设计一个类。
class Palindromial {
public:
class PalindromialIterator {
public:
PalindromialIterator(Palindromial * rhs_palindromial) : palindromial(rhs_palindromial) {}
int operator*() const { return palindromial->current(); }
Palindromial * operator++( if (palindromial->next() {
return self;
} else {
return palindromial->end();
}
bool operator==(PalindromialIterator const & rhs) {
return palindromial == rhs.palindromial;
}
private:
Palindromial * palindromial;
};
bool next(); //Updates current an returns true if there was an element.
int current() const; //Returns the current value in the sequence.
PalindromialIterator begin() { return PalindromialIterator(self); }
PalindromialIterator end() { return PalindromialIterator(0); }
};
我没有尝试编译这段代码,但我希望你能理解。您还需要考虑需要支持哪些算法以及它们所需的运算符。
答案 2 :(得分:0)
Python通过实现生成器函数来处理这个问题。生成器函数仅在需要时生成列表的元素,并且不会一次性将它们存储在内存中。您可以使用此question中讨论的C ++实现类似的结构。
理想情况下,您可以将之前的数字存储在表格中,以便生成自下而上而不是自上而下。
但是,对于回文数字,您不需要这样做。您需要做的就是计算给定模式的可能性数量。例如,对于1位数,x
可以匹配0到9之间的所有10个数字。对于2位数,xx
可以匹配9个数字(零已经包含在单个数字中) 。对于xyx
,回文数量为9 * 10(因为前导零无效)。对于xyyx
,9 * 10是有效的回文。
根据模式,您无需实际生成递归数字,您只需根据给定索引生成数字。例如,索引0应返回单个数字模式中的第一个,0。索引100应返回3位数字xyx
的数字的(100 - 9 - 10 =)索引81。知道该模式的第一个数字是101,并且每个第一个数字有10个有效数字,索引81处的元素将是919(909在索引80处)。