C++进阶-STL容器,你看我就够了

本文详细介绍了C++中的STL容器,包括string、vector、deque、stack、queue、list、priority_queue、set、multiset、map和multimap。讲解了各种容器的基本用法、插入删除操作、遍历方式、以及特性和适用场景,帮助读者深入理解STL的容器体系。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

STL(标准模板库),是目前C++内置支持的library。它的底层利用了C++类模板和函数模板的机制,由三大部分组成:容器、算法和迭代器。

目前STL有六大组件

  • 容器 container
  • 算法 algorthm
  • 迭代器 iterator
  • 仿函数 function object
  • 适配器 adaptor
  • 空间配置器 allocator

下面,我们会一一进行介绍。

STL初探

容器是STL中很重要的一种数据结构。常见的容器包括

  • vector容器
  • deque双端数组
  • stack栈模型
  • queue队列模型
  • list链表模型
  • priotriy_queue优先级队列
  • set与multiset容器
  • map与multimap容器

除了容器,STL还封装了强大的算法,能够实现查找、删除、替换、删除等很多常见操作。后面会重点讲解。

另外,迭代器也是STL重要的一环,通过迭代器,我们可以很方便对容器中的元素进行遍历,以及操作容器。后面我们会穿插讲解迭代器。

STL中的string

string是STL的字符串类型,在C语言中,我们通常用char *或者char[]字符数组来表示字符串。C++的string和C语言的char *有什么区别呢?

  • string是一个类,char *是指向字符的指针
  • string封装了char *,管理这个字符串,是一个char *类型的容器
  • string不用考虑内存释放和数组越界
  • string提供了一些列的字符串操作函数

string的构造函数

既然string是一个类,那么也就有构造函数,我们研究下string的构造函数。

#include <iostream>
using namespace std;
int main(int argc, const char * argv[]) {
    
    //通过const char * 初始化
    string s1 = "aaaa";
    
    //构造函数初始化
    string s2("bbbbb");
    
    //通过拷贝构造函数来初始化对象s3
    string s3 = s2;
    
    //用10个'a'字符来初始化字符串
    string s4(10, 'a');
    
    return 0;
}

字符串的遍历

字符串的遍历,有三种遍历的方式

  • 数组方式遍历,通过[]操作符遍历 (不会抛出异常)
  • at()方法遍历,根据index取值 (会抛出异常)
  • 通过STL迭代器遍历
int main(int argc, const char * argv[]) {
    
    //创建字符串对象
    string str("abcdefg");
    
    //数组形式遍历
    for (int i = 0; i < str.length(); i++) {
        cout<< str[i] << endl;
    }
    
    //at方法遍历
    for (int i = 0; i < str.length(); i++) {
        cout << str.at(i) << endl;
    }
    
    //迭代器遍历
    for (string::iterator it = str.begin(); it != str.end(); it++) {
        cout << *it << endl;
    }

    return 0;
}

数组方式和at方法方式,有一个明显的不同

  • 数组方式,如果出现越界或者其他错误,不会抛出异常,程序直接终端。
  • at()方法遍历,出现越界或其他错误,会抛出异常,程序可以处理异常。

迭代器其实可以看作是一个字符的指针,上个例子中string::iterator it = str.begin()就是定义一个string类型的迭代器,指向str的第一次位置。*it就表示当前的字符。注意str.end()表示字符串最后一个字符的后面一个位置。如果it == str.end()就表示已经遍历到终点了。

string与char *的转换

string提供了成员函数c_str来将string对象转化成const char *。string提供了copy(buf,size,begin)成员函数来讲string从begin位置开始的size个字符拷贝到buf中。需要注意的是:

  • 如果buf容纳不下,会越界
  • 拷贝过去后,不会转变成C风格的字符串,也就是不会在buf后面添加'\0'
int main(int argc, const char * argv[]) {
    
    //1 string转char *
    string str("aaaaaa");
    const char *p = str.c_str();
    
    //2 char *转string
    const char *p1 = "12345";
    string str2 = p1;
    
    //3 string拷贝到buf[]中
    char buf[128] = {0};
    //从0开始,拷贝3个字符到buf指向的内存空间
    //如果buf空间容纳不下,会越界
    //拷贝过去时,不会给buf末尾添加\0
    str.copy(buf, 3, 0);

    return 0;
}

string的拼接

string为我们提供了两种字符串拼接方式,一种是重写了 + 操作符,我们可以直接将连个字符串相加,类似于java的语法。另一种是string提供了成员函数append()供我们拼接连个字符串.

int main(int argc, const char * argv[]) {
    
    string s1 = "123456";
    string s2 = "abcdef";
    
    //直接使用加号运算符拼接
    string s3 = s1 + s2;
    
    //使用成员函数拼接
    string s4 = s1.append(s2);
    
    cout<<s3<<endl;
    cout<<s4<<endl;
    
    return 0;
}

string的查找和替换

string类提供了find函数,用来查找字符串中指定的字符。提供了replace函数,用来替换字符串中指定位置的字符串。

replace函数是,先删除指定位置,指定长度的字符,然后在当前指定位置插入新的字符。

int main(int argc, const char * argv[]) {
    
    
    string s1 = "hello hello hello hello hello hello 1234 7876";
    
    //从0位置开始查找第一个hello出现的首位位置
    size_t index1 = s1.find("hello",0);
    cout << index1 << endl;
    
    //查找第一个hello出现时的首位位置
    size_t index2 = s1.find_first_of("hello");
    cout << index2 << endl;
    
    //查找最后一个hello出现时的末尾位置
    size_t index3 = s1.find_last_of("hello");
    cout << index3 << endl;
    
    //求hello出现的次数,以及对应的下标
    int count = 0;
    size_t offindex = s1.find("hello",0);
    while (offindex != string::npos) {  //如果 offindex != -1
        //找到了
        cout << "索引:" << offindex <<endl;
        count++;
        offindex++;
        offindex = s1.find("hello", offindex);
    }
    
    //把hello替换成welcome
    size_t offindex1 = s1.find("hello", 0);
    while (offindex1 != string::npos) {
        
        //从offindex1的位置开始删除5个位置,并插入新的字符串welcome
        s1.replace(offindex1, strlen("hello"), "welcome");
        
        //从后面的位置开始
        offindex1 += strlen("welcome");
        
        //继续查找
        offindex1 = s1.find("hello", offindex1);
    }
    cout << "替换后的字符串:" << s1 <<endl;

    return 0;
}

string区间删除和插入

string提供了inserterase分别实现插入和删除操作。

插入:pos位置插入字符串s,返回新的string。

  • string &insert(int pos, const char *s)
  • string &insert(int pos, const string &s)

插入:pos位置插入n个字符c,返回string。

  • string &insert(int pos, int n, char c)

删除:删除从pos位置开始的n个字符,返回新的string

  • string &erase(int pos, int n)

删除:删除指定迭代器的位置,返回当前迭代器位置

  • string::iterator erase(string::iterator it)

删除:删除迭代器之间的字符,左闭右开区间

  • string::iterator erase(string::iterator beginIt, string::iterator endIt)
int main(int argc, const char * argv[]) {
    
    string s1 = "hello1 world!";
    
    //1 删除字符串中的'1'
    //---通过find函数,查找'1'所在的迭代器位置
    string::iterator it = find(s1.begin(), s1.end(), '1');
    //---删除
    if (it != s1.end()) {
        s1.erase(it);
    }
    cout << s1 << endl;
    
    //2 删除起始迭代器位置的字符
    s1.erase(s1.begin(), s1.begin() + 3);
    cout << s1 << endl;
    
    //3 在0位置插入"AAA"
    s1.insert(0, "AAA");
    cout << s1 << endl;
    
    return 0;
}

string算法相关

目前常见的string的算法是大小写转换。一般使用函数transform来进行转换。

int main(int argc, const char * argv[]) {
    
    string s1 = "abcdefg";
    string s2 = "AEDLFLKJDLKJFL";
    
    //小写全部转换成大写,转换的结果放在s1.begin()的位置,后面的操作需要强制转换成指定的函数类型
    transform(s1.begin(), s1.end(), s1.begin(), (int (*)(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值