欢迎光临
我们一直在努力

C++ STL 完整入门笔记[0]:从概念到string实战刷题

一、什么是 STL

STL 全称 Standard Template Library 标准模板库,是 C++ 标准库核心组成部分。 它不只是一堆可复用工具函数,更是一套封装数据结构 + 通用算法的完整软件框架。 C++ 标准库整体分为三块:C 库、IO 库、STL,STL 是其中模板化、容器化的核心模块。

二、STL 四大历史版本

STL 起源惠普实验室,衍生出 4 个主流分支,不同平台底层实现不同:

  • HP 原始版本(始祖) Alexander Stepanoff、Meng Lee 在惠普实验室开发,开源协议宽松:允许商用、修改、分发,唯一要求衍生代码同样开源。所有 STL 实现的底层源头。

  • P.J. 版本(Windows) 继承 HP 版本,被 VS (Visual C++) 采用,闭源商用。缺点:代码可读性差、命名风格怪异,无法查看修改底层源码。

  • RW 版本(旧版 Windows/macOS) Rogue Wave 公司出品,闭源商用,用于老版 C++ Builder,可读性一般。

  • SGI 版本(Linux/GCC,学习首选) Silicon Graphics 公司开发,继承 HP,GCC 编译器默认实现。 优势:完全开源、可自由修改分发、命名规范、源码注释清晰。学习 STL 底层原理、阅读源码首选 SGI 版本。

  • 三、STL 六大核心组件(整体架构)

    一张图看懂 STL 完整分层:

  • 容器 Container(数据结构) 存储数据的结构,分为三类:

  • 顺序容器:string、vector、list、deque

  • 关联容器:map、set、multimap、multiset

  • 容器适配器(改造容器):stack、queue、priority_queue

  • 算法 Algorithm 通用操作函数,与容器解耦:sort、reverse、find、swap、merge 等。 核心设计:一套算法,适配所有容器,不靠容器内置方法实现。

  • 迭代器 Iterator 容器和算法的桥梁,模拟指针行为:iterator、const_iterator、reverse_iterator、const_reverse_iterator。 算法只操作迭代器,不感知底层容器结构,实现低耦合。

  • 仿函数 Functor 重载()的类,用作算法比较规则:greater、less,替代函数指针,功能更强。

  • 空间配置器 Allocator 容器底层内存池管理,封装内存分配、释放逻辑,优化内存碎片。

  • 配接器 Adapter 分容器适配器、迭代器适配器、函数适配器,对原有组件二次封装(如 stack 基于 deque 改造)。

  • STL 学习三层境界

  • 第一层:熟用 STL —— 会调用容器、算法解决业务 / 算法题

  • 第二层:吃透底层 —— 理解模板泛型原理、容器底层实现、迭代器解耦逻辑

  • 第三层:扩展 STL —— 自定义容器、仿函数、分配器,造轮子

  • 四、string 字符串详解

    1. string 底层体系:宽字符与编码

    std::string 本质是模板别名:

    typedef basic_string<char> string;

    配套多字节宽字符串,适配 Unicode 编码:

    • wstring:basic_string<wchar_t> 老 Windows 宽字符

    • u16string:basic_string<char16_t> UTF-16 编码

    • u32string:basic_string<char32_t> UTF-32 编码

    编码概念区分:

    • ASCII:单字节英文老字符集

    • Unicode:字符 – 符号映射表(统一给全球文字分配编号)

    • UTF-8/UTF-16/UTF-32:Unicode 的存储编码方案(变长 / 定长存储)

    UTF-8 变长编码规则(连蒙带猜快速识别)

    UTF-8 是 1~4 字节变长编码,通过首字节高位判断字符占用字节:

  • 首字节以0开头:单字节 ASCII 字符

  • 首字节110开头:双字节字符

  • 首字节1110开头:三字节字符

  • 首字节11110开头:四字节字符 后续延续字节统一以10开头。

  • 2. string 核心接口

    (1)npos 静态常量

    static const size_t npos = -1;

    字符串查找失败时的返回标记,无匹配字符就返回npos。

    (2)下标访问 operator []

    string s1("hello world");
    const string s2("hello world");

    s1[0]++;  // 可读写,非const字符串
    s2[0]++;  // 编译报错,const字符串仅可读

    底层存储:_str字符数组指针、_size有效长度、_capacity总容量。

    (3)迭代器遍历

    迭代器是模仿指针的对象,begin()获取首元素迭代器,end()获取末尾后一位迭代器:

    string::iterator it1 = s1.begin();
    while (it1 != s1.end())
    {
        (*it1)–;
        ++it1;
    }
    cout << s1 << endl;

    3. 通用算法 reverse:解耦设计精髓

    std::reverse 是函数模板,接收一对双向迭代器,反转区间[first, last)内元素:

    // string反转
    reverse(s1.begin(), s1.end());
    // vector反转
    reverse(v.begin(), v.end());
    // list反转
    reverse(lt.begin(), lt.end());

    迭代器 + 算法的两大核心意义
  • 统一遍历接口:vector、list、string 结构完全不同,但都能用begin/end迭代器遍历,写法统一。

  • 容器与算法解耦:算法不依赖容器底层结构,只操作迭代器;新增容器只要实现迭代器,所有 STL 算法直接复用,不用重写反转、排序逻辑。

  • 五、LeetCode string 实战刷题

    例题 1:917. 仅仅反转字母

    题目规则:仅反转英文字母,非字母字符位置保持不变。 双指针思路:左指针从头、右指针从尾,跳过符号数字,交换两边字母。

    class Solution {
    public:
        bool isLetter(char ch)
        {
            if(ch >= 'a' && ch <= 'z') return true;
            if(ch >= 'A' && ch <= 'Z') return true;
            return false;
        }
        string reverseOnlyLetters(string s) {
            size_t begin = 0, end = s.size()-1;
            while(begin < end)
            {
                while(begin < end && !isLetter(s[begin]))
                    ++begin;
                while(begin < end && !isLetter(s[end]))
                    –end;
                swap(s[begin], s[end]);
                ++begin;
                –end;
            }
            return s;
        }
    };

    例题 2:387. 字符串中的第一个唯一字符

    思路:数组统计 26 个小写字母出现次数,第二次遍历找到第一个计数为 1 的下标。

    class Solution {
    public:
        int firstUniqChar(string s) {
            int count[26] = {0};
            // 统计频次
            for(auto ch : s)
            {
                count[ch-'a']++;
            }
            // 遍历找第一个仅出现一次的字符
            for(size_t i = 0; i < s.size(); ++i)
            {
                if(count[s[i]-'a'] == 1)
                    return i;
            }
            return -1;
        }
    };

    六、学习总结

  • STL 核心价值:模板泛型实现数据结构 + 算法复用,大幅减少重复造轮子;

  • 迭代器是 STL 灵魂,实现算法与容器解耦,一套算法通用所有容器;

  • string 基于basic_string模板封装,区分多套宽字符适配不同编码;

  • 刷题优先掌握迭代器遍历、双指针、计数数组三大 string 常用技巧。

  • 赞(0)
    未经允许不得转载:171主机测评 » C++ STL 完整入门笔记[0]:从概念到string实战刷题
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址