迭代器介绍
迭代器(iterator):容器类型内置的“指针”
- 使用迭代器可以访问某个元素,迭代器也能从一个元素移动到另一个元素。
- 有迭代器的类型都拥有 begin 和 end 成员
- begin:返回指向第一个元素(或字符)的迭代器
- end:尾后迭代器,即尾元素的下一个位置(一个本不存在的元素)
使用迭代器
auto b = v.begin(),e = v.end(); // b和e的类型相同
如果容器为空,则begin和end返回的是同一个迭代器,都是尾后迭代器
举个例子,下面利用迭代器实现
string s = "some string";
if(s.begin() != s.end()) { //确保s非空
auto it = s.begin(); //it表示s的第一个字符
*it = toupper(*it); //将当前字符改成大写形式
} //Some string
使用迭代器遍历容器
for(auto it = s.begin(); it != s.end() && !isspace(*it); ++it) {
*it = toupper(*it);
} // SOME string
- 迭代器类型
vector<int>::iterator it; //it能读写元素
vector<int>::const_iterator it2;//it2只能读元素,不可以写元素
如果vector或者string对象是一个常量,只能使用const_iterator;如果不是常量,则既能使用iterator也能使用const_iterator
- 正序迭代
begin();end() //iterator
cbegin();cend() //const_iterator
- 逆序迭代
rbegin();rend() //reverse_iterator
int main() {
vector<int> vec{0,1,2,3,4,5,6,7,8,9};
vector<int>::reverse_iterator it;
for (it = vec.rbegin(); // 迭代器指向最后一个元素
it != vec.rend(); // rend() 指向第一个元素的前一个
++it) // ++操作访问前一个元素
cout << *it<< " "; // prints 9,8,7,...0
return 0;
}
迭代器解引用
vector<string> vec;
auto it = vec.begin();
(*it).empty() //检查vector中的元素是否为空,只需检查it所指字符串是否为空
- 箭头运算符(->)
it->mem & (*it).mem 表达的意思相同
WARNING
任何一种可能改变vector对象容量的操作,比如push_back,都会使该vector对象的迭代器失效。
但凡是使用了迭代器的循环体,都不要向迭代器所属的容器添加元素。
迭代器运算
或者是两个迭代器相减,就可以得到中间隔了多少个元素。
使用迭代器运算的一个经典算法是二分搜索:
vector<int> text = {1,2,3,4,5};
auto sought = 2;
auto beg = text.begin(), end = text.end();
auto mid = beg + (end - beg) / 2; //初始状态的中间点
while(mid != end && *mid != sought) {
if(sought < *mid) end = mid;
else beg = mid + 1;
mid = beg + (end - beg) / 2; //新的中间点
}
循环过程终止时,mid或者等于end或者指向要找的元素。如果说mid等于end,说说明text中没有我们要找的元素。