c++笔记容器和迭代器

C++中的迭代器是一个功能强大的工具,用于遍历和操作容器中的元素。深入理解迭代器的类型、特性和用法,以及如何与各类容器配合使用,是编写高效、健壮C++代码的关键。下面将深入探讨迭代器的概念、与容器的配合使用、以及注意事项。

迭代器类型

  1. 输入迭代器:支持只读访问,允许单次遍历序列。常用于算法的输入操作。
  2. 输出迭代器:支持只写访问,允许单次遍历序列。常用于算法的输出操作。
  3. 前向迭代器:支持读写访问,允许多次遍历序列。常用于链表等容器。
  4. 双向迭代器:支持前向和后向遍历,允许多次遍历序列。常用于链表、集合、映射等容器。
  5. 随机访问迭代器:支持常数时间的随机访问,允许多次遍历序列。常用于数组、向量、双端队列等容器。

迭代器与容器的配合使用

1. std::vector

std::vector使用随机访问迭代器,支持高效的随机访问和顺序遍历。

示例代码

#include <iostream>
#include <vector>

int main() {
    std::vector<int> vec = {1, 2, 3, 4, 5};

    // 正向遍历
    for (auto it = vec.begin(); it != vec.end(); ++it) {
        std::cout << *it << " ";
    }
    std::cout << std::endl;

    // 反向遍历
    for (auto rit = vec.rbegin(); rit != vec.rend(); ++rit) {
        std::cout << *rit << " ";
    }
    std::cout << std::endl;

    return 0;
}
2. std::list

std::list使用双向迭代器,支持高效的前向和后向遍历。

示例代码

#include <iostream>
#include <list>

int main() {
    std::list<int> lst = {1, 2, 3, 4, 5};

    // 正向遍历
    for (auto it = lst.begin(); it != lst.end(); ++it) {
        std::cout << *it << " ";
    }
    std::cout << std::endl;

    // 反向遍历
    for (auto rit = lst.rbegin(); rit != lst.rend(); ++rit) {
        std::cout << *rit << " ";
    }
    std::cout << std::endl;

    return 0;
}
3. std::deque

std::deque使用随机访问迭代器,支持高效的随机访问和双端操作。

示例代码

#include <iostream>
#include <deque>

int main() {
    std::deque<int> deq = {1, 2, 3, 4, 5};

    // 正向遍历
    for (auto it = deq.begin(); it != deq.end(); ++it) {
        std::cout << *it << " ";
    }
    std::cout << std::endl;

    // 反向遍历
    for (auto rit = deq.rbegin(); rit != deq.rend(); ++rit) {
        std::cout << *rit << " ";
    }
    std::cout << std::endl;

    return 0;
}
4. std::mapstd::set

std::mapstd::set使用双向迭代器,支持有序遍历。

示例代码

#include <iostream>
#include <map>
#include <set>

int main() {
    std::map<int, std::string> mp = {{1, "one"}, {2, "two"}, {3, "three"}};
    std::set<int> st = {1, 2, 3, 4, 5};

    // 遍历map
    for (auto it = mp.begin(); it != mp.end(); ++it) {
        std::cout << it->first << ": " << it->second << std::endl;
    }

    // 遍历set
    for (auto it = st.begin(); it != st.end(); ++it) {
        std::cout << *it << " ";
    }
    std::cout << std::endl;

    return 0;
}
5. std::unordered_mapstd::unordered_set

std::unordered_mapstd::unordered_set使用前向迭代器,支持无序遍历。

示例代码

#include <iostream>
#include <unordered_map>
#include <unordered_set>

int main() {
    std::unordered_map<int, std::string> ump = {{1, "one"}, {2, "two"}, {3, "three"}};
    std::unordered_set<int> ust = {1, 2, 3, 4, 5};

    // 遍历unordered_map
    for (auto it = ump.begin(); it != ump.end(); ++it) {
        std::cout << it->first << ": " << it->second << std::endl;
    }

    // 遍历unordered_set
    for (auto it = ust.begin(); it != ust.end(); ++it) {
        std::cout << *it << " ";
    }
    std::cout << std::endl;

    return 0;
}

迭代器操作函数

以下是所有标准容器通用的迭代器操作函数:

  • begin(): 返回指向容器第一个元素的迭代器。
  • end(): 返回指向容器末尾的迭代器(指向最后一个元素之后的位置)。
  • rbegin(): 返回指向容器最后一个元素的反向迭代器。
  • rend(): 返回指向容器第一个元素之前位置的反向迭代器。
  • cbegin(): 返回指向容器第一个元素的常量迭代器。
  • cend(): 返回指向容器末尾的常量迭代器。
  • crbegin(): 返回指向容器最后一个元素的常量反向迭代器。
  • crend(): 返回指向容器第一个元素之前位置的常量反向迭代器。

迭代器使用注意事项

  1. 迭代器失效问题

    • 对容器进行插入、删除等修改操作可能会导致迭代器失效。特别是在std::vectorstd::deque中,插入和删除操作可能会导致重新分配和拷贝,从而使迭代器失效。
    • std::list和关联容器(如std::mapstd::set)在进行插入和删除操作时,其迭代器通常不会失效。
  2. 避免越界访问

    • 迭代器的end()指向的是容器末尾元素之后的位置,访问该位置会导致未定义行为。因此,遍历时要确保迭代器没有超出end()
  3. 常量迭代器

    • 使用常量迭代器(如const_iterator)可以防止意外修改容器中的元素,增强代码的安全性和可读性。
    • 常量迭代器只能读取元素,不能修改元素。
  4. 范围循环

    • C++11引入的范围循环提供了更简洁的语法进行遍历,推荐在不需要显式迭代器的情况下使用:
      std::vector<int> vec = {1, 2, 3, 4, 5};
      for (int val : vec) {
          std::cout << val << " ";
      }
      std::cout << std::endl;
      
  5. 算法库结合使用

    • C++标准库提供了一组强大的算法,如std::for_eachstd::findstd::sort等,这些算法通常结合迭代器使用,能简化代码并提高可读性。
      #include <algorithm>
      #include <vector>
      #include <iostream>
      
      int main() {
          std::vector<int> vec = {4, 2, 3, 1, 5};
      
          // 使用std::sort排序
          std::sort(vec.begin(), vec.end());
      
          // 使用std::for_each遍历并打印
          std::for_each(vec.begin(), vec.end(), [](int val) {
              std::cout << val << " ";
          });
          std::cout << std::endl;
      
          return 0;
      }
      

通过深入理解迭代器的类型和用法,以及与各类容器的配合使用,可以编写更加高效、健壮和可维护的C++代码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Tech Embedded

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值