首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >【C++】基础:STL标准库常用模块使用

【C++】基础:STL标准库常用模块使用

作者头像
DevFrank
发布2024-07-24 15:12:41
发布2024-07-24 15:12:41
7210
举报

😏★,°:.☆( ̄▽ ̄)/$:.°★ 😏 这篇文章主要介绍标准库常用模块使用。 学其所用,用其所学。——梁启超 欢迎来到我的博客,一起学习,共同进步。 喜欢的朋友可以关注一下,下次更新不迷路🥞

文章目录
  • :smirk:1. STL介绍
  • :blush:2. 常用容器模块
    • string:字符串,抽象char*
    • vector:动态数组,支持快速随机访问。
    • list:双向链表,支持高效的插入和删除操作。
    • queue:队列
    • deque:双端队列,支持首尾插入和删除操作。
    • set:集合,存储唯一值,并按照一定的排序规则进行自动排序。
    • map:映射,存储键值对,按照键的大小进行自动排序。
    • unordered_set:无序集合,存储唯一值,并提供常数时间的查找操作。
    • unordered_map:无序映射,存储键值对,并提供常数时间的查找操作。
  • :satisfied:3. 常用算法模块
    • sort:对容器进行排序。
    • find:在容器中查找指定元素。
    • binary_search:二分查找
    • remove:从容器中移除指定值。
    • transform:对容器中的元素应用某个操作并存储结果。
    • accumulate:计算容器中元素的累加值。
    • count:计算容器中满足条件的元素个数。
    • reverse:反转容器中的元素顺序。
    • replace:替换
  • :satisfied:3. 常用迭代器模块
    • 输入迭代器(Input Iterators):只读访问容器中的元素。
    • 输出迭代器(Output Iterators):只写访问容器中的元素。
    • 正向迭代器(Forward Iterators):支持读写容器中的元素,并能够向前遍历。
    • 双向迭代器(Bidirectional Iterators):支持正向和逆向遍历。
    • 随机访问迭代器(Random Access Iterators):支持任意位置的高效随机访问。
  • :satisfied:3. 其他模块
    • 函数对象(Function Objects)
    • 适配器(Adapters):
    • 分配器(Allocators):
    • 迭代器标签(Iterator Tags):
    • 元编程技术(Metaprogramming Techniques):

😏1. STL介绍

C++标准模板库(Standard Template Library,STL)是C++中的一个重要组成部分,提供了丰富的容器、算法和函数模板,可以帮助开发人员快速实现通用的数据结构和算法。STL的设计目标是提供高效、可靠、易于使用的工具,以提高开发效率和代码可维护性。

STL主要包含以下三个组件:

容器(Containers): 容器是STL中用于存储和管理数据的类模板。STL提供了各种不同类型的容器,包括动态数组(vector)、双向链表(list)、队列(queue)、栈(stack)、集合(set)、映射(map)等。每种容器都具有不同的特点和适用场景,开发人员可以根据需要选择合适的容器来存储和操作数据。

算法(Algorithms): 算法是STL中用于处理容器中数据的函数模板。STL提供了大量的算法,包括查找、排序、合并、替换、计数等。这些算法实现了常见的数据处理操作,并且对于多数情况下都有高效的实现。开发人员可以通过简单地调用这些算法,而无需自己实现复杂的数据处理逻辑。

迭代器(Iterators): 迭代器是STL中用于遍历容器中元素的抽象概念。通过使用迭代器,开发人员可以在不关心具体容器实现的情况下,对容器中的元素进行迭代和访问。STL提供了多种类型的迭代器,包括输入迭代器、输出迭代器、正向迭代器、双向迭代器和随机访问迭代器。不同类型的迭代器支持不同的操作和功能,开发人员可以根据需要选择适合的迭代器。

STL的优点有:

1.可重用性:STL提供了通用的数据结构和算法,可以在不同的项目和场景中重复使用,避免了重复编写相似的代码。 2.高效性:STL中的容器和算法都经过了优化,具有高效的实现。STL使用了模板和内联函数等技术,在编译时生成高效的代码。 3.可扩展性:STL支持用户自定义类型的容器和算法,可以根据实际需求进行扩展和定制。 4.代码可读性和可维护性:STL提供了一致的接口和命名规范,使得代码更易于理解和维护。同时,STL中的容器和算法都经过了广泛测试和验证,具有较高的可靠性。

两个在线学习地址:

代码语言:javascript
复制
https://cui-jiacai.gitbook.io/c++-stl-tutorial/
https://zoupers.gitbook.io/cpp-17-stl-cookbook/

😊2. 常用容器模块

容器主要有序列容器(array、vector、dequeue、forward_list、list)和关联容器(map、set、multimap、multiset),分别用于不同的数据存储和访问方式。

string:字符串,抽象char*
代码语言:javascript
复制
    std::string str("hello");
    // 后面追加
    str.append(" world");
    // 前面插入
    str.insert(0, "ok,");
    // 截取子字符串
    str = str.substr(3);
    printf("sub str=%s\n", str.c_str());
    // 空格替换为逗号
    for (int i = 0; i < str.size(); ++i) {
        char ch = str.at(i);
        if (ch == ' ') {
            str.replace(i, 1, 1, ',');
        }
    }
    // 后面添加字符
    str.push_back('!');
    // 删除指定位置的字符
    str.erase(str.size() - 1);
    size_t pos = str.find("world");
    printf("find pos=%ld\n", pos);
    // 判断字符串是否相等,==属于操作符重载
    if (str == "hello,world") {
        // ...
	}
vector:动态数组,支持快速随机访问。
代码语言:javascript
复制
#include <iostream> 
#include <vector> 
#include <array> 
using namespace std;
int main()
{
	std::vector<int> demo{ 1,2 };

	demo.push_back(1);	//push_back操作
	
	std::vector<int>test{ 3,4,5 };
	demo.insert(demo.end(), test.begin(), test.end());//inset操作

	// 循环打印值
	for (int i = 0; i < demo.size(); i++) {
		cout << demo[i] << " ";
	}

	// 使用迭代器 iterator 访问值
	vector<int>::iterator v = demo.begin();
	while (v != demo.end()) {
		cout << "value of v = " << *v << endl;
		v++;
	}
	return 0;
}
list:双向链表,支持高效的插入和删除操作。
代码语言:javascript
复制
#include <iostream>
#include <list>

int main() {
    // 创建一个空的list容器
    std::list<int> myList;

    // 在容器尾部插入元素
    myList.push_back(10);
    myList.push_back(20);
    myList.push_back(30);

    // 在容器头部插入元素
    myList.push_front(5);

    // 使用迭代器遍历输出容器中的元素
    std::cout << "List elements: ";
    for (auto it = myList.begin(); it != myList.end(); ++it) {
        std::cout << *it << " ";
    }
    std::cout << std::endl;

    // 在指定位置插入元素
    auto insertPos = std::find(myList.begin(), myList.end(), 20);
    if (insertPos != myList.end()) {
        myList.insert(insertPos, 15);
    }

    // 使用迭代器反向遍历输出容器中的元素
    std::cout << "Reversed List elements: ";
    for (auto rit = myList.rbegin(); rit != myList.rend(); ++rit) {
        std::cout << *rit << " ";
    }
    std::cout << std::endl;

    // 移除指定值的元素
    myList.remove(10);

    // 清空容器
    myList.clear();

    return 0;
}
queue:队列
代码语言:javascript
复制
    std::queue<int> queue;
    // 入队
    queue.push(111);
    queue.push(222);
    queue.push(333);
    printf("queue front=%d, back=%d", queue.front(), queue.back());
    // 出队
    while (!queue.empty()) {
        int front = queue.front();
        queue.pop();
    }
deque:双端队列,支持首尾插入和删除操作。
代码语言:javascript
复制
#include <iostream>
#include <deque>

int main() {
    // 创建一个空的deque容器
    std::deque<int> myDeque;

    // 在容器尾部插入元素
    myDeque.push_back(10);
    myDeque.push_back(20);
    myDeque.push_back(30);

    // 在容器头部插入元素
    myDeque.push_front(5);

    // 使用索引访问和输出容器中的元素
    std::cout << "Deque elements: ";
    for (size_t i = 0; i < myDeque.size(); ++i) {
        std::cout << myDeque[i] << " ";
    }
    std::cout << std::endl;

    // 在指定位置插入元素
    auto insertPos = myDeque.begin() + 2;
    myDeque.insert(insertPos, 15);

    // 使用迭代器遍历输出容器中的元素
    std::cout << "Deque elements after insertion: ";
    for (auto it = myDeque.begin(); it != myDeque.end(); ++it) {
        std::cout << *it << " ";
    }
    std::cout << std::endl;

    // 移除指定位置的元素
    auto erasePos = myDeque.begin() + 1;
    myDeque.erase(erasePos);

    // 使用迭代器反向遍历输出容器中的元素
    std::cout << "Reversed Deque elements: ";
    for (auto rit = myDeque.rbegin(); rit != myDeque.rend(); ++rit) {
        std::cout << *rit << " ";
    }
    std::cout << std::endl;

    // 清空容器
    myDeque.clear();

    return 0;
}
set:集合,存储唯一值,并按照一定的排序规则进行自动排序。
代码语言:javascript
复制
#include <iostream>
#include <set>

int main() {
    // 创建一个空的set容器
    std::set<int> mySet;

    // 向容器中插入元素
    mySet.insert(10);
    mySet.insert(20);
    mySet.insert(20);  // 重复的元素将被忽略
    mySet.insert(30);

    // 判断元素是否存在
    if (mySet.find(20) != mySet.end()) {
        std::cout << "Element 20 is found in the set." << std::endl;
    } else {
        std::cout << "Element 20 is not found in the set." << std::endl;
    }

    // 输出容器中的元素个数
    std::cout << "Size of set: " << mySet.size() << std::endl;

    // 使用范围循环遍历输出容器中的元素
    std::cout << "Set elements: ";
    for (const auto& element : mySet) {
        std::cout << element << " ";
    }
    std::cout << std::endl;

    // 移除元素
    int key = 10;
    mySet.erase(key);

    // 检查容器是否为空
    if (mySet.empty()) {
        std::cout << "Set is empty." << std::endl;
    } else {
        std::cout << "Set is not empty." << std::endl;
    }

    return 0;
}
map:映射,存储键值对,按照键的大小进行自动排序。
代码语言:javascript
复制
#include <iostream>
#include <map>
#include <string>
using namespace std;
int main()
{
    map<string,int> phone_book; // 创建一个map类容器,用于存储电话号码簿
    
    // 创建电话簿
    phone_book["zhangsan"] = 12345678; // 通过[]操作和关键字往容器中加入元素
    phone_book["lisi"] = 87654321;
    phone_book["wanger"] = 56781234;
    phone_book.insert(std::pair<string, int>("zhangtian", 65458997));
    // ......
    // 输出电话号码簿
    cout << "电话号码簿的信息如下:\n";
    for (pair<string, int> item: phone_book) 
    // for (auto it = phone_book,begin(); it != phone_book.end(); it++)
    // C++11中引入的enhanced-for loop
        cout << item.first << ": " << item.second << endl; 
    // 输出元素的姓名和电话号码

    // 查找某个人的电话号码
    string name;
    cout << "请输入要查询号码的姓名:";
    cin >> name;
    map<string,int>::const_iterator it; // 创建一个不能修改所指向的元素的迭代器
    it = phone_book.find(name); // 查找关键字为name的容器元素
    if (it == phone_book.end()) // 判断是否找到
        cout << name << ": not found\n"; // 未找到
    else
        cout << it->first << ": " << it->second << endl; // 找到
    return 0;
}
unordered_set:无序集合,存储唯一值,并提供常数时间的查找操作。
unordered_map:无序映射,存储键值对,并提供常数时间的查找操作。

😆3. 常用算法模块

sort:对容器进行排序。
代码语言:javascript
复制
    std::vector<int> array{3, 6, 1, 5, 9, 2, 8};
    std::sort(array.begin(), array.end());
    for (int it: array) {
        printf("%d ", it);
    }
find:在容器中查找指定元素。
代码语言:javascript
复制
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
int main() 
{
	int a[10] = { 10,20,30,40 };
	vector<int> v;
	v.push_back(1);    v.push_back(2);
	v.push_back(3);    v.push_back(4); //此后v里放着4个元素:1,2,3,4

	// 定义迭代器,用find查找
	vector<int>::iterator p;
	p = find(v.begin(), v.end(), 3); //在v中查找3
	if (p != v.end()) //若找不到,find返回 v.end()
		cout << "1. " << *p << endl; //找到了
	p = find(v.begin(), v.end(), 9);
	if (p == v.end())
		cout << "not found " << endl; //没找到

	p = find(v.begin() + 1, v.end() - 1, 4); //在,3 这两个元素中查找4
	cout << "2. " << *p << endl;

	int * pp = find(a, a + 4, 20);
	if (pp == a + 4)
		cout << "not found" << endl;
	else
		cout << "3. " << *pp << endl;

	return 0;
}
binary_search:二分查找
代码语言:javascript
复制
bool result = std::binary_search(array.begin(), array.end(), 8);
remove:从容器中移除指定值。
transform:对容器中的元素应用某个操作并存储结果。
accumulate:计算容器中元素的累加值。
count:计算容器中满足条件的元素个数。
reverse:反转容器中的元素顺序。
代码语言:javascript
复制
std::reverse(array.begin(), array.end());
replace:替换
代码语言:javascript
复制
std::replace(array.begin(), array.end(), 6, 666);

😆3. 常用迭代器模块

输入迭代器(Input Iterators):只读访问容器中的元素。
输出迭代器(Output Iterators):只写访问容器中的元素。
正向迭代器(Forward Iterators):支持读写容器中的元素,并能够向前遍历。
双向迭代器(Bidirectional Iterators):支持正向和逆向遍历。
随机访问迭代器(Random Access Iterators):支持任意位置的高效随机访问。

😆3. 其他模块

函数对象(Function Objects)

STL提供了函数对象类模板,允许用户自定义函数对象(也称为仿函数),以便在算法中使用。 函数对象是一个行为类似于函数的对象,可以重载函数调用运算符 operator()()。 使用函数对象可以实现更加灵活的算法操作,包括自定义的排序规则、条件判断等。

适配器(Adapters):

STL提供了适配器类模板,用于将容器或迭代器的接口进行适配或扩展,以满足特定的需求。 常见的适配器有 stack、queue、priority_queue,它们在底层使用了不同的容器实现,并且提供了特定的接口和功能。

分配器(Allocators):

STL允许用户自定义内存分配器,用于控制容器内部的内存管理和分配策略。 用户可以通过实现自己的分配器类来满足特定的内存管理需求,例如内存池、定制的内存分配策略等。

迭代器标签(Iterator Tags):

STL中引入了迭代器标签的概念,用于表示迭代器的类型和特性。 迭代器标签包括输入迭代器、输出迭代器、前向迭代器、双向迭代器和随机访问迭代器,用于指定迭代器支持的操作和功能。

元编程技术(Metaprogramming Techniques):

STL广泛使用元编程技术,包括模板特化、模板偏特化、模板元编程、SFINAE(Substitution Failure Is Not An Error)等。 元编程技术可以在编译期间进行计算和代码生成,以提高代码的效率和灵活性。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-01-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文章目录
  • 😏1. STL介绍
  • 😊2. 常用容器模块
    • string:字符串,抽象char*
    • vector:动态数组,支持快速随机访问。
    • list:双向链表,支持高效的插入和删除操作。
    • queue:队列
    • deque:双端队列,支持首尾插入和删除操作。
    • set:集合,存储唯一值,并按照一定的排序规则进行自动排序。
    • map:映射,存储键值对,按照键的大小进行自动排序。
    • unordered_set:无序集合,存储唯一值,并提供常数时间的查找操作。
    • unordered_map:无序映射,存储键值对,并提供常数时间的查找操作。
  • 😆3. 常用算法模块
    • sort:对容器进行排序。
    • find:在容器中查找指定元素。
    • binary_search:二分查找
    • remove:从容器中移除指定值。
    • transform:对容器中的元素应用某个操作并存储结果。
    • accumulate:计算容器中元素的累加值。
    • count:计算容器中满足条件的元素个数。
    • reverse:反转容器中的元素顺序。
    • replace:替换
  • 😆3. 常用迭代器模块
    • 输入迭代器(Input Iterators):只读访问容器中的元素。
    • 输出迭代器(Output Iterators):只写访问容器中的元素。
    • 正向迭代器(Forward Iterators):支持读写容器中的元素,并能够向前遍历。
    • 双向迭代器(Bidirectional Iterators):支持正向和逆向遍历。
    • 随机访问迭代器(Random Access Iterators):支持任意位置的高效随机访问。
  • 😆3. 其他模块
    • 函数对象(Function Objects)
    • 适配器(Adapters):
    • 分配器(Allocators):
    • 迭代器标签(Iterator Tags):
    • 元编程技术(Metaprogramming Techniques):
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档