C++STL用法总结

93 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第26天

1.string

string是一个字符串。

    //1.创建字符串
    string s1;//建立空串
    string s2("hello world");//初始化
    string s3(s2, 2);//用s2从第二个字符开始后面的所有字符对s3初始化(不包括第二个字符)
    string s4(s2, 2, 6);//用s2从第二个字符开始后6个字符对s4初始化(不包括第二个)
    string s5(s4);//用s4对s5初始化
​
​
    //2.容量函数
    s2.size();//不包括\0
    s2.capacity();//字符串的容量
    s2.clear();//清除字符串
    s2.reserve(100);
    cout << s2.capacity() << endl;//reserve扩展的空间是在原有字符串大小基础上扩展的,而不是在原有容量的基础上
                                  //与vector不同,vector是扩容到
    s3.resize(100,'x');//扩容并初始化,共初始化100个空间,即100-11个x
    cout << s3.size() << endl;
    cout << s3.capacity() << endl;
​
​
    //3.下标
    cout << s3[2] << endl;
​
​
    //4.插入,都是将后面数据后移,并且首元素下标都是0
    s1.push_back('a');//插入字符
    s1.append("apple");//插入字符串
    s1 += "hello world";//运算符重载,最常使用!!!
    s1.insert(0, 1, 'x');//在0的位置插入一个x
    s1.insert(s1.begin(), 'y');//在开始插入一个y
    s1.insert(4, "test");//在第四个位置插入test
    s1.erase(0, 1);//删除头处第一个字符
​
​
    //5.查找与匹配
    string file("test.txt");
    size_t pos = file.find('.');//返回第一次出现的位置(从0开始计数),失败会返回string::nops
    size_t ppos = file.find('x', 3);//从第三个位置开始找,但是还是从0开始计数,结果为6
    cout << ppos << endl;
    if (pos != string::npos)
    {
        string suffix = file.substr(pos, file.size() - pos);//截取从pos(包括pos)开始file.size()-pos长度的字符串
        cout << pos << " " << suffix << endl;//没有指定就截取后面整个内容
    }
​
    //6.字符串比较,和strcmp的原理一样
    cout << (s1 < s2) << endl;
​
    //7.字符串转换
    int val = stoi("1234");
    string str = to_string(3.14);

2.vector

vector是一个数组,可以下标访问。

    //1.vector创建数组
    vector<int> v1;//创建一个空对象
    vector<int> v11;//创建一个空对象
    vector<int> v2(10, 8);//创建有十个8的对象
    vector<int> v3(v2.begin()+1, --v2.end());//通过迭代器创建对象
    vector<int> v4(v3);//拷贝构造
    //将字符串存到vector数组中
    string a("hello world");
    vector<char> v5(a.begin(), a.end());
​
​
    //2.vector容量函数
    v2.size();//已经初始化的元素个数10
    v2.capacity();//最大容量为10
​
​
    //3.vector扩容函数
    //注意是扩容到多少,而不是扩容了多少
    v1.reserve(10);//扩容,但不进行初始化
    v1.size();//0
    v1.capacity();//10
    v11.resize(10);//扩容,并且进行初始化为0
    v11.size();//10
    v11.capacity();//10
    v2.resize(20);//之前的值不进行覆盖
    v2.size();//20
    v2.capacity();//20
    v2.assign(20, 5);//扩容为20,并将所有值覆盖为5
​
​
    //4.插入与删除
    vector<int> v6;
    v6.push_back(1);//尾插,可以自动扩容(扩容可能比插入的多)
    v6.push_back(1);
    v6.push_back(1);
    v6.pop_back();//尾删,但不改变容量
    //迭代器插入(慎用)
    //1.如果空间被重新分配,则指向容器的迭代器、指针和引用都会失效。
    //2.如果空间没被重新分配,指向插入位置之前的元素的迭代器、指针和引用依然有效,
    //但指向插入位置之后元素的带带器、指针和引用将会失效。
    vector<int>::iterator ret = v6.begin();
    v6.insert(ret, 0);//在ret位置处插入0,此时ret失效不能再使用
    v6.insert(v6.begin(), 0);//可自动扩容
    v6.erase(v6.begin());//不改变容量删除
    v6.clear();//删除所有数据,不改变容量
    cout << v6.size() << endl; cout << v6.capacity() << endl;
​
​
    //5.遍历vector
    v1.resize(10);
    //正常遍历
    for (int i = 0; i < v1.size(); i++)
    {
        v1[i] += i;
        cout << v1[i] << " ";
    }
    cout << endl;
    //迭代器遍历,将其当成指针
    vector<int>::iterator it = v1.begin();
    while (it != v1.end())
    {
        *it -= 1;
        cout << *it<<" ";
        it++;
    }
    cout << endl;
    //范围for遍历
    for (auto& e : v1)
    {
        cout << e << " ";
    }
    cout << endl;
    
​
    //6.二维数组
    //分两批初始化,第一次初始化多少行,第二次初始化每行多少元素
    vector<vector<int>> vv;
    vv.resize(10);
    for (auto& e : vv)
    {
        e.resize(5);
    }
    cout << vv[1][3] << endl;

3.list

list是一个双向带头循环链表,不能下标访问。

    //1.创建双向带头循环链表
    list<int> l1;//创建一个空对象
    list<int> l11;//创建一个对象
    list<int> l2(8, 1);//链表中有8个1,算头有9个节点
    list<int> l3(l2);//拷贝构造
    list<int> l4(l3.begin()++, l3.end()--);//注意不能+1,但是可以++//2.大小
    //由于是链表,所以不需要提前扩容
    //size大小不算头结点
    l1.empty();//1
    l1.size() ;//0
    l2.empty();//0
    l2.size();//8//3.插入删除
    l1.push_back(2);//尾插
    l1.push_back(2);
    l1.push_front(3);//头插
    l1.push_front(3);
    l1.pop_back();//尾删
    l1.pop_front();//头删
    auto it = l1.begin();
    l1.insert(it, 5);//在it前面插入一个5,需要注意迭代器是否失效问题
    l1.insert(it, 3, 5);//在it前面插三个5
    l1.insert(it, l2.begin(), l2.end());//将l2插在it前面
    l1.erase(it);//删除节点
    l1.erase(++l1.begin(), --l1.end());//删除中间内容//4.遍历
    //迭代器遍历
    list<int>::iterator cur = l3.begin();
    while (cur != l3.end())
    {
        cout <<*cur<<" ";
        cur++;
    }
    cout << endl;
    //范围for遍历
    for (auto& e : l3)
    {
        cout << e << " ";
    }
    cout << endl;
​
    //排序,交换,清空
    l1.sort();//从小到大排序,vector可以使用algorithm中的sort进行排序
    l1.swap(l3);//两个链表中内容进行交换
    l1.clear();//清空l1中的元素

4.set与multiset

set是只有key值的二叉搜索树。multiset是只有key值,并且可以有key值相等节点的二叉搜索树。

    //搜索二叉树的key模型,不能修改key
    //1.set建立与插入
    set<int> s;//不能插入key相同的节点
    s.insert(1);//插入的时候不会插入相同节点
    s.insert(1);
    s.insert(5);
    s.insert(3);
    s.insert(2);
    s.insert(4);
​
​
    //2.set查找与删除
    set<int>::iterator it = s.find(3);//find函数返回的是迭代器类型,没找到会返回s.end()
    if (it != s.end())//每一次删除都要对find的返回值做检测
    {
        s.erase(it);
    }
    s.erase(1);//即使传入的值不存在也不会崩溃,底层做了检测//3.遍历,都是进行中序遍历,即从小到大排序
    //迭代器遍历
    auto cur = s.begin();
    while (cur != s.end())
    {
        cout << *cur << " ";
        cur++;
    }
    cout << endl;
    //范围for遍历
    for (auto& e : s)
    {
        cout << e << " ";
    }
    cout << endl;
​
    //4.multiset,可以有key相同的值
    multiset<int> ms;
    ms.insert(1);
    ms.insert(2);
    ms.insert(5);
    ms.insert(3);
    ms.insert(3);
    ms.insert(3);
    ms.find(3);//中序遍历的第一个3
    ms.erase(3);//删除所有的3

5.map与multimap

有kv结构的二叉搜索树,mutimap支持相同的key进行插入(value可以不同也可以相同)。

    //有kv结构的二叉搜索树
    //1.创建,map中只能存放pair类型,key不能修改,value可以修改
    map<string, string> dict;
    pair<string, string> kv1("sort", "排序");
​
​
    //2.插入删除
    dict.insert(kv1);
    dict.insert(pair<string, string>("string", "字符串"));
    dict.insert(make_pair("test", "测试"));//通常使用make_pair来进行插入
    dict.insert(make_pair("test", "检验"));//不允许有相同的key值,没有插入进去
    dict.insert(make_pair("apple", "苹果"));
    dict.erase("apple");//注意传入的是key值//3.下标的使用
    dict["string"] = "绳子";//可以根据key_value进行修改
​
​
    //4.遍历,每一个节点表示一个pair
    //迭代器遍历
    map<string, string>::iterator it = dict.begin();
    while (it != dict.end())
    {
        cout << (*it).first << ":" << (*it).second << endl;
        it++;
    }
    //范围for遍历
    for (auto& e : dict)
    {
        cout << e.first << ":" << e.second << endl;
    }
​
    //5.multimap,即可以同一个key不同的value
    multimap<string, string> dictt;
    dictt.insert(make_pair("left", "左边"));
    dictt.insert(make_pair("sort", "排序"));
    dictt.insert(make_pair("left", "左边"));
    dictt.insert(make_pair("left", "剩余"));
    dict.count("left");//2,计算left的个数
    dict.erase("left");//删除所有的left
    //注意!!!!!multimap是不支持下标访问的!!!!