shellex瞎谈迭代器
以前给别人义务普及C++,我总是说:这个iterator哈,和指向数组元素的指针差不多…. :p
好吧,GOF是这么定义迭代器模式的:提供一种方法访问一个容器(container)对象中各个元素,而又不需暴露该对象的内部细节。
我看起来这个东东,在程序的设计过程中扮演的角色是提供了一个很好的抽象,对容器操作的抽象。所以我们的STL里面的vector啦list啦都用它。iterator是在std这个命名空间下,可见有多NB。
其实也没有那么NB。由于C++这类语言不支持闭包和匿名函数,于是才进化出了用迭代器的这样子的东东。好啦,现在请大家举起手来,跟我一起喊:“一,二,三”,Bingo:
for (vecto::iterator iter = v.begin(); iter != v.end(); ++iter) {
//do sth...
}
来想象一下每次打上面这些东西时你淌着哈喇子嚼着鼻涕嘎子的样子。 因为我可以这样子:
v.each_items(lambda (x){...});
(C++的STL里面倒是提供了foreach函数,但是编写迭代器的复杂性和额外的小函数负担使我不喜欢使用他)
不管如何,iterator的表现已经很好了。作为Lazy Evaluation的实现倒也不会太丑。Lazy Evaluation这种东西其实很常用的,可以让你保持优雅的程序的程序结构的同时保证这些code有效率。
比如说我们经常会发现最容易理解的程序往往不是最高效的(还记得斐波那契函数的树型递归吗)。
再比如说聪明的MM大多不养眼,养眼的MM大多不聪明,养眼又聪明的MM大多插在便便上。就是这样令人恼火。惰性求值就可以帮你解决部分生理问题和部分心理问题。
假设我要找出区间[a, b]中第n个素数,比如a = 10, b = 100, n = 4。好吧,不够严谨,我省略了很多东西,能表达意思就行。这说明在C++里面搞个迭代器真的蛮费劲,所以我就大概…将就一下。
#include
#include
using std::cout;
using std::endl;
typedef int* prime_iterator;
class prime_set {
public:
prime_set(int low, int high) : _low(low), _high(high), _crr_pos(low){ };
prime_iterator begin() {
int i = _low;
for (; i < _high; ++i) {
if (is_prime(i)) {
_crr_pos = i + 1;
return &_crr_pos;
}
}
return NULL;
}
prime_iterator end() {
return NULL;
}
prime_iterator next() {
int i = _crr_pos + 1;
for (; i < _high; ++i) {
if (is_prime(i)) {
_crr_pos = i ;
return &_crr_pos;
}
}
return NULL;
}
private:
int is_prime(int n) {
int i = 2;
for (; i <= sqrt(n); ++i) {
if (n % i == 0) {
return 0;
}
}
return 1;
}
int _low;
int _high;
int _crr_pos;
};
int prime_list_ref(prime_set &ps, int idx) {
int cnt = 0;
for (prime_iterator i = ps.begin();
i != ps.end();
i = ps.next(), ++cnt)
{
if (cnt == idx) {
return *i;
}
}
return 0;
}
int main() {
prime_set ps(10, 100);
cout<
