内容来自c++ primer 第五版
个人理解,迭代器是一种类似于指针类型,用来访问类似string或者vector等对象以及容器的工具。
使用:
迭代器的begin()和end()成员,begin()成员负责返还指向第一个元素的迭代器,end()返回指向容器或者一些对象的末尾元素的下一个位置。
如果容器为空,则begin和end()返回的是用一个迭代器,都是尾后迭代器。
vector<int> vi;
auto b = vi.begin() , e=vi.end();
if(b == e)
cout<<1<<endl;//由于vi为空,结果输出1
else
cout<<0<<endl;
这里的C++11 标准中的 auto 可以自动判断类型,不用再像以前一样写vector::iterator。
迭代器运算符:
迭代器可以使用==和!=来比较两个合法的迭代器是否相等,如果迭代器指向的元素相同或者都是同一个容器的尾后迭代器,则它们相等;否则不相等。
vector<int> vi={1,2,3,4,5,6,7};
auto b = vi.begin() , e=vi.end();
auto mid = b + vi.size()/2;
for ( ; b != e ; b++)
{
if(b == mid)
cout<<"mid="<<*b<<endl;
else
cout<<*b<<endl;
}
//结果
1
2
3
mid=4
5
6
7
标准容器迭代器运算符 | 解释 |
---|---|
*iter | 返回迭代器iter所指元素的引用 |
iter->name | 解引用iter并获取该元素名为mem的成员,等价于(*iter).mem |
++iter,iter++ | 令iter指示容器中的下一个元素 |
–iter,iter– | 指示上一个元素 |
iter1 == iter2 | 判断两个迭代器是否相等,两个迭代器是否指向同一个元素 |
iter1 !=iter2 | 是否不相等 |
//样例
struct node
{
int a,b;
};
vector<node> vn;
int a,b;
for(int i=1;i<=5;i++)
{
cin>>a>>b;
node t;
t.a=a,t.b=b;
vn.push_back(t);
}
for(auto in = vn.begin(); in != vn.end(); in++)
cout<<in->a<<" "<<in->b<<endl;
for(auto in = vn.begin(); in != vn.end(); in++)
cout<<(*in).a<<" "<<(*in).b<<endl;
迭代器类型:
书中目前介绍了两种迭代器类型,一种是普通的iterator另一种是const_iterator。其中const_iterator与常量指针差不多,只能读取但不能修改它所指向的元素,iterator对象可读可写。
如果vector对象或string对象是个常量,只能使用const_iterator;如果vector对象或string对象不是常量,那么只能使用iterator也能使用const_iterator。
其中,begin和end返回的具体类型由对象是否是常量决定,如果对象是常量,begin和end返回const_iterator;如果对象不是常量,返回iterator
const vector<int> vi={1,2,3,4,5};
vector<int> vj(5,0);
auto bi = vi.begin() , ei = vi.end();
auto bj = vj.begin() , ej = vj.end();
(*bi)++;//错误,bj是const_iterator
(*bj)++;
C++11标准引入了两个新函数,cbegin() 和 cend() ,用来返回对象或者容器的第一个元素和最后一个元素的下一个位置,但是返回的都是const_iterator。
const vector<int> vi={1,2,3,4,5};
vector<int> vj(5,0);
auto bi = vi.cbegin() , ei = vi.cend();
auto bj = vj.cbegin() , ej = vj.cend();
(*bi)++;//错误
(*bj)++;//错误
迭代器失效:
容器或对象在获取了迭代器以后,如果改变了对象或者容器,迭代器就会失效。
vector<string> vj= {"abc", "asd", "qwe" };
auto bj = vj.begin() , ej = vj.end();
vj.push_back("iostream");//结果是段错误
for(; bj!=ej ; bj++)
cout<<*bj<<endl;
迭代器运算:
string和vector的迭代器提供了更多额外的运算符,一方面使得迭代器的每次移动跨过多个元素,也支持迭代器进行关系运算。
string和vector迭代器运算 | 解释 |
---|---|
iter + n | 返回一个位置为当前迭代器向后移动n个位置的迭代器 |
iter - n | 返回一个位置为当前迭代器向前移动n个位置的迭代器 |
iter +=n | 将iter加n的结果赋给iter |
iter -=n | 将iter减n的结果赋给iter |
iter1 - iter2 | 返回两个迭代器之间的距离,两个迭代器必须指向同一个容器或对象 |
, >= , < ,<= | 关系运算符 |
vector<int> vi = {0,1,2,3,4,5,6,7,8,9,10};
cout<<vi.end() - vi.begin()<<" "<<vi.begin() - vi.end()<<endl;//11 -11
for(auto it = vi.begin(); it < vi.end() ;it+=2)
cout<<*it<<endl;
//二分查找
bool BinSearch(const vector<int> &v, int key)
{
auto beg = v.begin();
auto en = v.end() ;
auto mid = v.begin() + (en - beg)/2;
while( mid != en)
{
if(*mid == key)
return true;
if(key > *mid)
beg = mid + 1;
else
en = mid ;
mid = beg + (en - beg)/2;
}
return false;
}
to be continue~