引言 C++ 标准模板库(STL)提供了一系列功能丰富的容器,这些容器不仅封装了数据结构,还提供了大量成员函数用于操作数据。此外,STL 还包含许多与容器配合使用的非成员函数,它们扩展了容器的功能,使操作更加灵活。
一、通用成员函数 几乎所有 STL 容器都提供了一组基础的通用成员函数,用于获取容器信息、修改容器状态等。
1.1 基本信息函数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 #include <iostream> #include <vector> #include <list> int main() { std::vector<int> vec = {1, 2, 3, 4, 5}; std::list<std::string> lst = {"apple", "banana", "cherry"}; // 容器大小相关 std::cout << "vector大小: " << vec.size() << std::endl; // 元素数量 std::cout << "list为空? " << (lst.empty() ? "是" : "否") << std::endl; // 是否为空 std::cout << "vector最大容量: " << vec.max_size() << std::endl; // 理论最大元素数 // 容器内容操作 vec.clear(); // 清空容器 std::cout << "vector清空后大小: " << vec.size() << std::endl; lst.resize(5, "grape"); // 调整大小,新增元素用"grape"填充 std::cout << "list调整大小后: " << lst.size() << std::endl; return 0; }
1.2 迭代器相关函数 所有容器都提供了获取迭代器的函数,用于遍历容器元素:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 #include <iostream> #include <set> int main() { std::set<int> s = {3, 1, 4, 1, 5, 9}; // 获取迭代器 auto it_begin = s.begin(); // 指向第一个元素的迭代器 auto it_end = s.end(); // 指向最后一个元素之后的迭代器 auto it_rbegin = s.rbegin(); // 指向最后一个元素的反向迭代器 auto it_rend = s.rend(); // 指向第一个元素之前的反向迭代器 // 常量迭代器(不能通过迭代器修改元素) auto it_cbegin = s.cbegin(); // const_iterator auto it_crend = s.crend(); // const_reverse_iterator std::cout << "正向遍历: "; for (auto it = it_begin; it != it_end; ++it) { std::cout << *it << " "; } std::cout << std::endl; std::cout << "反向遍历: "; for (auto it = it_rbegin; it != it_rend; ++it) { std::cout << *it << " "; } std::cout << std::endl; return 0; }
二、序列容器特有成员函数 序列容器(如vector、list、deque等)提供了一系列针对序列结构的特有函数。
2.1 元素访问函数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 #include <iostream> #include <vector> #include <deque> int main() { std::vector<int> vec = {10, 20, 30, 40, 50}; std::deque<std::string> dq = {"first", "second", "third"}; // 访问元素 std::cout << "vector第一个元素: " << vec.front() << std::endl; // 第一个元素 std::cout << "vector最后一个元素: " << vec.back() << std::endl; // 最后一个元素 std::cout << "vector[2]: " << vec[2] << std::endl; // 随机访问 std::cout << "vector.at(3): " << vec.at(3) << std::endl; // 带边界检查的访问 // 修改元素 vec.front() = 100; vec.back() = 500; dq[1] = "modified"; std::cout << "修改后vector: "; for (int num : vec) { std::cout << num << " "; } std::cout << std::endl; return 0; }
2.2 插入与删除函数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 #include <iostream> #include <list> int main() { std::list<int> lst = {1, 2, 3}; // 插入元素 lst.push_back(4); // 在末尾插入 lst.push_front(0); // 在开头插入 auto it = lst.begin(); std::advance(it, 2); // 移动迭代器到第3个元素 lst.insert(it, 100); // 在迭代器位置插入 std::cout << "插入后: "; for (int num : lst) { std::cout << num << " "; } std::cout << std::endl; // 删除元素 lst.pop_back(); // 删除末尾元素 lst.pop_front(); // 删除开头元素 auto it2 = lst.begin(); std::advance(it2, 1); lst.erase(it2); // 删除迭代器指向的元素 std::cout << "删除后: "; for (int num : lst) { std::cout << num << " "; } std::cout << std::endl; return 0; }
2.3 vector 特有的容量管理函数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 #include <iostream> #include <vector> int main() { std::vector<int> vec; vec.reserve(100); // 预留存储空间,避免多次内存分配 std::cout << "容量: " << vec.capacity() << ", 大小: " << vec.size() << std::endl; for (int i = 0; i < 20; ++i) { vec.push_back(i); } std::cout << "容量: " << vec.capacity() << ", 大小: " << vec.size() << std::endl; vec.shrink_to_fit(); // 减少容量以匹配大小 std::cout << "收缩后容量: " << vec.capacity() << ", 大小: " << vec.size() << std::endl; return 0; }
三、关联容器特有成员函数 关联容器(如set、map、multiset、multimap)提供了基于键的操作函数。
3.1 查找与计数函数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 #include <iostream> #include <map> #include <set> int main() { std::map<std::string, int> score = { {"Alice", 90}, {"Bob", 85}, {"Charlie", 95} }; std::multiset<int> nums = {3, 1, 4, 1, 5, 9, 2, 6, 5}; // map查找 auto it = score.find("Bob"); if (it != score.end()) { std::cout << "Bob的分数: " << it->second << std::endl; } // 计数 std::cout << "multiset中5的个数: " << nums.count(5) << std::endl; // 范围查找 auto range = nums.equal_range(5); std::cout << "multiset中所有的5: "; for (auto it = range.first; it != range.second; ++it) { std::cout << *it << " "; } std::cout << std::endl; return 0; }
3.2 插入与删除函数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 #include <iostream> #include <set> #include <map> int main() { std::set<int> s; std::map<int, std::string> m; // 插入元素 auto [it1, inserted1] = s.insert(5); // C++17返回pair<iterator, bool> std::cout << "5是否插入成功? " << (inserted1 ? "是" : "否") << std::endl; auto [it2, inserted2] = s.insert(5); // 重复插入 std::cout << "再次插入5是否成功? " << (inserted2 ? "是" : "否") << std::endl; // map插入 m.insert({1, "one"}); m.insert(std::make_pair(2, "two")); // 删除元素 size_t erased = s.erase(5); // 返回删除的元素个数 std::cout << "删除的元素个数: " << erased << std::endl; return 0; }
四、无序容器特有成员函数 无序容器(如unordered_set、unordered_map)提供了与哈希相关的特有函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 #include <iostream> #include <unordered_map> int main() { std::unordered_map<std::string, int> um = { {"apple", 5}, {"banana", 3}, {"cherry", 7} }; // 哈希桶相关操作 std::cout << "桶数量: " << um.bucket_count() << std::endl; std::cout << "负载因子: " << um.load_factor() << std::endl; std::cout << "最大负载因子: " << um.max_load_factor() << std::endl; // 查找元素所在的桶 std::string key = "banana"; std::cout << key << "所在的桶: " << um.bucket(key) << std::endl; std::cout << "该桶中的元素数量: " << um.bucket_size(um.bucket(key)) << std::endl; // 重新哈希 um.rehash(20); // 设置桶数量至少为20 std::cout << "重新哈希后桶数量: " << um.bucket_count() << std::endl; return 0; }
五、容器相关的非成员函数 STL 提供了许多非成员函数,用于操作容器,这些函数通常比成员函数更通用。
5.1 比较函数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 #include <iostream> #include <vector> #include <algorithm> // 比较函数所在头文件 int main() { std::vector<int> v1 = {1, 2, 3, 4}; std::vector<int> v2 = {1, 2, 3, 4}; std::vector<int> v3 = {1, 2, 3}; // 容器比较 if (v1 == v2) { std::cout << "v1与v2相等" << std::endl; } if (v3 < v1) { std::cout << "v3小于v1" << std::endl; } return 0; }
5.2 交换函数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 #include <iostream> #include <list> #include <algorithm> int main() { std::list<int> a = {1, 2, 3}; std::list<int> b = {4, 5, 6}; std::cout << "交换前: "; for (int num : a) std::cout << num << " "; std::cout << "| "; for (int num : b) std::cout << num << " "; std::cout << std::endl; // 交换两个容器内容 std::swap(a, b); std::cout << "交换后: "; for (int num : a) std::cout << num << " "; std::cout << "| "; for (int num : b) std::cout << num << " "; std::cout << std::endl; return 0; }
5.3 迭代器辅助函数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 #include <iostream> #include <vector> #include <iterator> // 迭代器辅助函数 int main() { std::vector<int> vec = {10, 20, 30, 40, 50}; // 计算迭代器距离 auto start = vec.begin(); auto end = vec.end(); std::cout << "容器长度: " << std::distance(start, end) << std::endl; // 移动迭代器 auto it = vec.begin(); std::advance(it, 2); // 向前移动2个位置 std::cout << "移动后迭代器指向: " << *it << std::endl; // 复制迭代器并移动 auto it2 = std::next(it); // it2指向it的下一个元素 auto it3 = std::prev(end); // it3指向end的前一个元素 std::cout << "*it2: " << *it2 << ", *it3: " << *it3 << std::endl; return 0; }
5.4 算法函数 虽然不属于容器成员函数,但 STL 算法常与容器配合使用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 #include <iostream> #include <vector> #include <algorithm> // 算法库 int main() { std::vector<int> vec = {3, 1, 4, 1, 5, 9}; // 排序 std::sort(vec.begin(), vec.end()); std::cout << "排序后: "; for (int num : vec) std::cout << num << " "; std::cout << std::endl; // 查找 int target = 5; auto it = std::find(vec.begin(), vec.end(), target); if (it != vec.end()) { std::cout << "找到" << target << ",位置: " << std::distance(vec.begin(), it) << std::endl; } // 计数 int count = std::count(vec.begin(), vec.end(), 1); std::cout << "1出现的次数: " << count << std::endl; return 0; }