17.STL 库(C++)plus

STL 库(C++)

1.迭代器

1.1 概述和分类

迭代器:

迭代器是 STL 库中的一个特殊工具,不属于容器本身,但是迭代器的获取需要通过容器。迭代器会根据容器的数据情况进行必要的初始化和限制操作。

可移动的,指针,可以通过迭代器进行数据的获取,查询,截取,添加操作。

迭代器类型描述
输入迭代器 (Input Iterator)用于读取数据序列的元素,只能使用前向迭代操作
输出迭代器 (Output Iterator)用于向数据序列写入元素,只能使用前向迭代操作
前向迭代器 (Forward Iterator)用于读写数据序列的元素,支持前向迭代操作
双向迭代器 (Bidirectional Iterator)用于读写数据序列的元素,支持前向和后向迭代操作
随机访问迭代器 (Random Access Iterator)用于读写数据序列的元素,支持随机访问操作和常数时间复杂度的元素访问
连续内存迭代器 (Contiguous Iterator)特殊形式的随机访问迭代器,用于在连续内存中移动
反向迭代器 (Reverse Iterator)反向封装其他迭代器,实现反向遍历操作

1.2案例

利用 STL 库中使用频类较高的 vertor 来演示迭代器

vector::iterator it = v1.begin();

iterator 是一个针对于当前 vector 容器的迭代器
是访问数据内容的一个【指针】,如果想要提取 vector 中
存储的数据内容,需要通过 *it 获取

#include <iostream>
#include <vector>

using namespace std;

int main(int argc, char const *argv[])
{
    vector<int> v1;

    v1.push_back(1);
    v1.push_back(2);
    v1.push_back(3);
    v1.push_back(4);
    v1.push_back(5);

    vector<int>::iterator it = v1.begin();

    /*
    iterator 是一个针对于当前 vector 容器的迭代器
    是访问数据内容的一个【指针】,如果想要提取 vector 中
    存储的数据内容,需要通过 *it 获取
    */
    cout << "v1 : " << *it << endl;
    it++;
    cout << "v1 : " << *it << endl; 

    cout << "=============================" << endl;
    for (vector<int>::iterator it2 = v1.begin(); it2 != v1.end(); it2++)
    {
        cout << "*it2 : " << *it2 << endl;
    }
    
    return 0;
}

2.C++ 的 string 类型

2.1string 概述

原则:

  • C/C++双引号包含的字符串内容,都是字符串常量
  • C/C++ 字符串都是以 ’\0‘ 结尾

字符串是开发中重要的数据载体

2.2 string 构造函数

// 创建一个字符串
string(); // string *s1 = new string;

// 使用一个 string 对象初始化另一个 string 对象
string(const string& str); // string *s3 = new string(arr);

// 使用字符串 s 初始化
string(const char * s);// string str = "字符串";

// 使用 n 个字符 c 初始化 v 
string(int n,char c);// string *s4 = new string(10,'a');
#include <iostream>
#include <string>

using namespace std;

int main(int argc, char const *argv[])
{
    string *s1 = new string;
    cout << *s1 << endl;

    string str = "最近天气升温,都是好天气";
    string *s2 = new string(str);
    cout << s2 << endl;
    cout << *s2 << endl;

    char arr[6] = {'1','2','3','4','5','\0'};
    string *s3 = new string(arr);
    cout << s3 << endl;
    cout << *s3 << endl;

    string *s4 = new string(10,'a');
    cout << s4 << endl;
    cout << *s4 << endl;
    return 0;
}

2.3 string 赋值操作

// char * 类型字符串赋值给当前字符串
string& operator = (const char* s);// string str1 = "xiaoyu";

// 把字符串 s 赋给当前的字符串 
string& operator = (const string &s); // string str1 = str2;

// 把字符赋值给当前的字符串
string& opeartor = (char c); // string str1 = 'A';

// 把字符串 s 赋给当前的字符串
string& assign(const char *s);// str1.assign(arr);

// 把字符串 s 的前 n 个字符赋给当前的字
string& assign(const char *s,int n);
//str1.assign(arr,3);
 
// 把字符串 s 赋给当前字符串
string& assign(const string &s);//str1.assign(str2);

// 用 n 个字符 c 赋给当前字符串
string& assign(int n, char c);// str1.saagin(10,'A');

// 将 s 从 start 开始 n 个字符赋值给字符串
string& assign(const string &s,int start,int n);// str1.assign(str6,3,3);
#include <iostream>
#include <string>

using namespace std;

int main(int argc, char const *argv[])
{
    string str1 = "zhangzhang";
    string str2 = str1;
    string str3;
    str3 = 'A';

    cout << "str1 : " << str1 << endl;
    cout << "str2 : " << str2 << endl;
    cout << "str3 : " << str3 << endl;

    string str5;
    char arr[6] = {'1','2','3','4','5','\0'};
    str5.assign(arr);
    cout << "str5 : " << str5 << endl;

    str5.assign(arr,3);
    cout << "str5 : " << str5 << endl;

    str5.assign(str1);
    cout << "str5 : " << str5 << endl;

    str5.assign(10,'C');
    cout << "str5 : " << str5 << endl;

    string str6 = "1234455666";
    str5.assign(str6,3,3);
    cout << "str5 : " << str5 << endl;
    return 0;
}

2.4string存取字符串操作

// 通过[] 方式取字符
char& operator[](int n);// str[2]

// 通过 at 方式获取
char& at(int n);// str.at(2)
#include <iostream>
#include <string>

using namespace std;

int main(int argc, char const *argv[])
{
    string str = "0123456789";

    cout << "\"0123456789[2]\" : " << "0123456789"[2] << endl; 
    cout << "str[2] : " << str[2] << endl;
    cout << "str.at(2) : " << str.at(2) << endl;
    return 0;
}

2.5string拼接操作

// 重载 += 操作符
string& operator+=(const string& str);

//重载 += 操作符
string& operator+=(const char* str);

// 重载 += 操作符
string& operator+=(const char c);

// 把字符串 s 连接到当前字符串结尾
string& append(const char* s);

// 把字符串 s 的前 n 个字符连接到当前字符串结尾
string& append(const char*s,int n);

// 同 operator+=()
string& append(const string &s);

// 把字符串 s 中从 pos 开始的 n 个字符连接到当前结尾


string& append(const string &s,int pos,int n);

// 在当前字符串结尾添加 n 个字符 c
string& append(int n,char c);
#include <iostream>
#include <string>

using namespace std;

int main(int argc, char const *argv[])
{
    string str1 = "12345";
    string str2 = "6789";
    str1 += str2;
    cout << "str1 : " << str1 << endl;
    return 0;
}

2.6 string 查找和替换

// 查找 str 第一次出现的位置
int find(const string& str,int pos = 0) const;

// 查找 s 第一次出现的位置,从 pos 开始查找
int find(const char* s,int pos = 0) const;

// 从 pos 位置查找 s 的前 n 个字符第一次位置
int find(const char* s,int pos,int n) const;

// 查找字符 c 第一次出现的位置
int find(const char c,int pos = 0) const;

// 查找 str 最后一次位置,从 pos 开始查找
int rfind(const string& str,int pos = npos) const;

// 查找 s 最后一次出现的位置,从 pos 开始查找
int rfind(const char*s,int pos = npos) const;

// 从 pos 查找 s 的前 n 个字符最后一次位置
int rfind(const char* s,int pos ,int n);

// 查找字符 C 最后一次出现位置
int rfind(const char c,int pos = 0);

// 替换从 pos 开始 n 个字符为字符串 str 
string& replace(int pos,int n,const string& str);

// 替换从 pos 开始的 n 个字符为字符串 s
string& replace(int pos,int n,const char* s);
#include <iostream>
#include <string>

using namespace std;

int main(int argc, char const *argv[])
{
    string str1 = "ABCDEFGABCDEFGABCDEFG";
    string str2 = "FGA";
    int index = str1.find(str2); // 第一次出现的下标
    cout << "index : " << index << endl;

    index = str1.find(str2,6); // 从 下标6 开始找
    cout << "index : " << index << endl;

    index = str1.find("BCD",10); // 查 BCD 从下标 10 开始找
    cout << "index : " << index << endl;

    index = str1.find("ABCGGGGG",5,3);// 从 str1 的 第 5 个开始找 "ABCGGGGG" 的前 3 个"ABC"
    cout << "index : " << index << endl;

    index = str1.find('G');
    cout << "index : " << index << endl;

    cout << "--------------------" << endl;

    int rIndex = str1.rfind("BC"); // 倒着查找
    cout << "rIndex : " << rIndex << endl;

    string str3 = "0111123456";
    string str5 = "ABCDEFGHI";

    str3.replace(1,4,str5); // 从下标 1 开始到下标 4 结束 替换成 str5
    cout << "str3 : " << str3 << endl;

    str3 = str3.replace(1,3,"000"); // 从下标 1 开始到下标 3 结束替换成 000
    cout << "str3 : " << str3 << endl;


    return 0;
}

2.7string 比较操作

/*
compare 函数在 > 时返回 1,< 时返回 -1,== 时返回 0。
比较区分大小写,比较时参考字典顺序,排越前面的越小,大写的 A 比小写的 a 小。
*/
// 与字符串 s 比较
int compare(const string &s) const;

// 与字符串 s 比较。
int compare(const char *s) const; 
#include <iostream>
#include <string>
#include <cstring>

using namespace std;

int main(int argc, char const *argv[])
{
    string str1 = "ABCDEFG";
    string str2 = "aBCDEFG";

    cout << str1.compare(str2) << endl;
    cout << str1.compare("ABCDEfG") << endl;

    cout << strcmp("ABC","aBC") << endl;
    return 0;
}

2.8string 子串

// 返回由 pos 开始的 n 个字符组成的字符串
string substr(int pos = 0,int n = npos) const;

// 获取字符串有效字符个数
size_t length();
#include <iostream>
#include <string>
#include <cstring>

using namespace std;

int main(int argc, char const *argv[])
{
    string str1 = "0123456789";

    cout << str1.substr(5,3) << endl; // 返回从 下标5 开始 3 个字符

    cout << str1.length() << endl; // 返回字符串长度
    return 0;
}

2.9string 插入和删除操作

// 插入字符串
string& insert(int pos,const char* s);

// 插入字符串
string& insert(int pos,string &str);

// 在指定位置插入 n 个字符 c 
string& insert(int pos,int n,cahr c);

//删除从 pos 开始的 n 个字符
string& erase(int pos,int n = npos);
#include <iostream>
#include <string>

using namespace std;

int main(int argc, char const *argv[])
{
    string str = "0123456789";

    str = str.insert(3,"ABCDEFG");// 从下标 3 插入字符串
    cout <<  "str : " << str << endl;

    string str1 = "666";
    str = str.insert(1,str1);// 从下标 1 插入字符串 str1
    cout << "str : " << str << endl;
    cout << "str : " << str.length() << endl;

    str= str.insert(15,10,'F');// 从下标 15 开始 插入 10 个字符 'F'
    cout << "str : " << str << endl;
    
    str = str.erase(5,10);// 从下标 5 开始 删除 10 个字符
    cout << "str : " << str << endl;

    return 0;
}

2.10 stirng 字符串转 c 语言字符串

// string 字符串转 c 语言字符串
const char * c_str();

// 例子:
const char* str2 = str.c_str(); 
    cout << str2 << endl;

3.vector

3.1概述

在这里插入图片描述

vector 底层是一个数组形式,而且是一个动态可变容量的数组。
提供的参数函数设计到数组末尾添加和删除,以及中间元素的获取,插入,遍历操作。
【常用容器】

vector 配合的迭代器是【双向可读可写迭代器】

3.2 vector构造函数

// 采用模板实现类实现,默认构造函数
vector<T> v;

// 将 v[begin(),end())区间中的元素拷贝给本身
vector(v.begin(),v.end());

// 构造函数将 n 个 elem 拷贝给本身。
vector(n,elem);

// 拷贝构造函数
vector(const vector &vec);
#include <iostream>
#include <vector>
#include <string>

using namespace std;

class Person
{
public:
    Person() {}
    Person(int id, string name, int age) : id(id), name(name), age(age) {}

    friend ostream &operator<<(ostream &o, Person *p);

private:
    int id;
    string name;
    int age;
};

ostream &operator<<(ostream & o,Person * p)
{
    o << "ID : " << p->id << "Name : " << p->name << "Age : " << p->age;
    return o;
}

int main(int argc, char const *argv[])
{
    vector<int> v;

    for (int i = 0; i < 10; i++)
    {
        v.push_back(i + 1);
    }
    vector<int> v2 = vector<int>(v.begin() + 1,v.end() - 1);
    for (vector<int>::iterator it = v2.begin(); it != v2.begin(); it++)
    {
        cout << "v2 : " << *it << endl;
    }
    
    vector<int> v4 = vector<int>(v2);
    for (vector<int>::iterator it = v4.begin(); it != v4.end();it++)
    {
        cout << "v4 : " << *it << endl;
    }
    
    vector<string> v3 = vector<string>(10,"嘟嘟嘟嘟");
    for (vector<string>::iterator it = v3.begin(); it != v3.end(); it++)
    {
        cout << "v3 : " << *it << endl;
    }

    vector<Person *> v5;

    for (int i = 0; i < 10; i++)
    {
        v5.push_back(new Person(i + 1,"郭7",15));
    }
    for (vector<Person *>::iterator it = v5.begin(); it != v5.end(); it++)
    {
        cout << "v5 : " << *it << endl;
    }

    return 0;
}

3.3vector 赋值操作

// 将[beg,end)区间中的数据拷贝赋值给本身
assign(v.begin(),v.end());

// 将 n 个elem 拷贝赋值给本身
assign(n,elem);

// 重载等号操作符
vector& operator = (const vector &vec);

// 将 vec 与本身的元素互换
swap(vec);
#include <iostream>
#include <vector>
#include <string>

using namespace std;

int main(int argc, char const *argv[])
{
    vector<string> v1;
    for (int i = 0; i < 10; i++)
    {
        v1.push_back("嘟嘟嘟笑死了");
    }

    vector<string> v2;
    v2.assign(v1.begin() + 2,v1.end() - 1);
    for (vector<string>::iterator it = v2.begin(); it != v2.end(); it++)
    {
        cout << "v2 : " << *it << endl;
    }
    
    vector<string> v3;
    v3.assign(5,"didididdddii");
    vector<string>::iterator it = v3.begin();

    while (it != v3.end())
    {
        cout << "v3 : " << *it << endl;
        it++;
    }

    vector<string> v4 = v3;
    vector<string>::iterator it2 = v4.begin();
    while (it2 != v4.end())
    {
        cout << "v4 : " << *it2 << endl;
        it2++;
    }

    vector<int> v5;
    vector<int> v6;

    v5.push_back(1);
    v5.push_back(2);
    v5.push_back(3);

    v6.push_back(10);
    v6.push_back(20);
    v6.push_back(30);

    v5.swap(v6);
    
    for (vector<int>::iterator it = v5.begin();
         it != v5.end();
         it++)
    {
        cout << "V5 : " << *it << endl;
    }
    
    return 0;
}

3.4vector大小操作

// 返回容器中元素的个数
size();

// 判断容器是否为空
empty();

//重新指定容器的长度为 num ,若容器变长,则以默认值填充新位置,如果容器变短,则末尾超出容器长度的元素被删除
resize(int num);

// 重新指定容器的长度为 num ,若容器变长,则以默认值填充新位置,弱国容器变短,则末尾超出容器长度的元素被删除
resize(int num,elem);

// 容器的容量
capacity();

// 容器预留 len 个元素,预留位置不初始化,元素不可访问
reserve(int len);
#include <iostream>
#include <vector>
#include <string>

using namespace std;

int main(int argc, char const *argv[])
{
    vector<int> v1;
    for (size_t i = 0;i < 10; i++)
    {
        v1.push_back(i + 1);
    }
    cout << "size : " << v1.size() << endl;
    cout << "capacity : " << v1.capacity() << endl;

    vector<string> v2;
    /*
    原码
    bool empty()
    {
        return 0 == size();
    }
    */
    cout << "empty : " << v2.empty() << endl;

    v1.resize(8);
    for (vector<int>::iterator it = v1.begin(); it != v1.end(); it++)
    {
        cout << "v1 : " << *it << endl;
    }

    cout << "size : " << v1.size() << endl;
    cout << "capacity : " << v1.capacity() << endl;

    vector<int> v3;
    for (size_t i = 0; i < 8; i++)
    {
        v3.push_back(i + 1);
    }

    v3.resize(12,5);
    cout << "size : " << v3.size() << endl;
    cout << "capacity : " << v3.capacity() << endl;
    for (vector<int>::iterator it = v3.begin(); it != v3.end(); it++)
    {
        cout << "v3 : " << *it << endl;
    }

    vector<int> v4;
    for (size_t i = 0; i < 8; i++)
    {
        v4.push_back(i + 1);
    }
    
    v4.reserve(40);
    cout << "size : " << v4.size() << endl;
    cout << "capacity : " << v4.capacity() << endl;
    for (int i = 0; i < 40; i++)
    {
        cout << v4[i] << endl;
    }
    
    

    return 0;
}

3.5vector数据存取操作

// 返回索引 idx 所指的数据,如果 idx 越界,抛出 out_of_range 异常
at(int idx);

// 返回索引 idx 所指的数据,越界时,运行直接报错
operator[];

// 返回容器中第一个数据元素
front();

// 返回容器中最后一个数据元素
back();
#include <iostream>
#include <vector>
#include <string>

using namespace std;

int main(int argc, char const *argv[])
{
    vector<int> v1 = vector<int>(10,5);

    cout << "v1[3] : " << v1[3] << endl;
    cout << "v1.at(3) : " << v1.at(3) << endl;

    cout << "v1.front() : " << v1.front() << endl;
    cout << "v1.back() : " << v1.back() << endl;
    return 0;
}

3.6vector插入和删除操作

//迭代器指向位置 pos 插入 count 个元素 ele
insert(const_iterator pos,int count,ele);

// 尾部插入元素 ele
push_back(ele);

// 删除最后一个元素
pop_back();

// 删除迭代器从 start 到 end 之间的元素
erase(const_iterator start,const_iterator end);

// 删除迭代器指向的元素
erase(const_iterator pos);

// 删除容器中所有元素
clear();
#include <iostream>
#include <vector>
#include <string>

using namespace std;

int main(int argc, char const *argv[])
{
    vector<int> v1;
    for (int i = 0; i < 10; i++)
    {
        v1.push_back(i + 1);
    }

    vector<int>::iterator it = v1.begin();

    
    v1.insert(it + 3, 3,6);// 下标位置插入3个6
    v1.pop_back();
    for (vector<int>::iterator it = v1.begin();it != v1.end(); it++)
    {
        cout << "v1: " << *it << endl;
    }
    
    cout << "======================" << endl;

    v1.erase(v1.begin() + 3,v1.begin() + 7);// 删除从。到 。
    
    v1.erase(v1.begin() + 6);
    for (vector<int>::iterator it = v1.begin();it != v1.end(); it++)
    {
        cout << "v1: " << *it << endl;
    }
    v1.clear(); // 删除所有

    cout << "v1.size():" << v1.size() << endl;
    cout << "v1.capacity() : " << v1.capacity() << endl; 

    
    return 0;
}

4.deque

在这里插入图片描述

在这里插入图片描述

4.1deque概述

  • 整体结构可以认为是 链表 + 数组,每一个链表结点中都存储目标数据类型数组,内存空间非连续
  • 访问效率低,因为内存空间非连续,需要进行指针跳转和结点之间数据结算操作,效率较低
  • 空间利用率较低,同时内存的碎片化情况较为复杂。后续有可能会影响其他程序使用。
  • deque 使用场景远不如 vector

4.2deque 构造函数

// 默认构造函数
deque<T>deqT; // deque<string> d1;

// 构造函数将[beg,end)区间中的元素拷贝给本身。
deque(beg,end); 
//deque<string>d2=deque<string(d1.begin()+2,d1.end());

// 构造函数将 n 个 elem 拷贝给本身
deque(n,elem);
// deque<string> d3 = deque<string>(10,"添加10个");

//拷贝构造函数
deque(const deque &deq);
// deque<string> d4 = deque<string>(d2);
#include <iostream>
#include <deque>
#include <string>

using namespace std;

int main(int argc, char const *argv[])
{
    deque<string> d1;
    d1.push_back("第一个");
    d1.push_back("第二个");
    d1.push_back("第三个");
    d1.push_back("第四个");

    for (deque<string>::iterator it = d1.begin(); it != d1.end(); it++)
    {
        cout << "d1: " << *it << endl;
    }
    cout << "=================" << endl;

    deque<string> d2 = deque<string>(d1.begin() + 2,d1.end());
    for (deque<string>::iterator it = d2.begin(); it != d2.end(); it++)
    {
        cout << "d2: " << *it << endl;
    }
    cout << "=================" << endl;
    
    deque<string> d3 = deque<string>(10,"添加10个");
    for (deque<string>::iterator it = d3.begin(); it != d3.end(); it++)
    {
        cout << "d3: " << *it << endl;
    }
    cout << "=================" << endl;

    deque<string> d4 = deque<string>(d2);
    for (deque<string>::iterator it = d4.begin(); it != d4.end(); it++)
    {
        cout << "d4: " << *it << endl;
    }
    cout << "=================" << endl;

    return 0;
}

4.3deque 赋值操作

// 将[bed,end)区间中的数据拷贝赋值给本身。
assign(beg,end);
//d2.assign(d1.begin() + 2,d1.end() - 2);

// 将 n 个 elem 拷贝赋值给本身
assign(n,elem);
//d3.assign(10,"追加10个");

//重载等号操作符
deque &operator=(const deque &deq);
// d4 = d3;

//将 deq 与本身的元素互换
swap(deq);
//d5.swap(d6);
#include <iostream>
#include <deque>
#include <string>

using namespace std;

int main(int argc, char const *argv[])
{
    deque<string> d1;
    d1.push_back("第一个");
    d1.push_back("第二个");
    d1.push_back("谨防诈骗");
    d1.push_back("注意各种安全");
    d1.push_back("龙行龘龘");
    d1.push_back("新年快乐!!!");
    d1.push_back("甲辰年青龙年!!!!");

    deque<string> d2;
    d2.assign(d1.begin() + 2,d1.end() - 2);

    for (deque<string>::iterator it = d2.begin(); it != d2.end() ; it++)
    {
        cout << "d2 : " << *it << endl;
    }
    cout << "=====================" << endl;

    deque<string> d3;
    d3.assign(10,"追加10个");

    for (deque<string>::iterator it = d3.begin(); it != d3.end(); it++)
    {
        cout << "d3 : " << *it << endl;
    }
    cout << "=====================" << endl;

    deque<string> d4;
    d4 = d3;
    for (deque<string>::iterator it = d4.begin(); it != d4.end(); it++)
    {
        cout << "d4 : " << *it << endl;
    }
    cout << "=====================" << endl;

    deque<string> d5;
    deque<string> d6;

    d5.push_back("今天中午吃什么");
    d5.push_back("今天中午吃大米菜");

    d6.push_back("明天早上吃什么");
    d6.push_back("明天早上吃包子");

    d5.swap(d6);
    for (deque<string>::iterator it = d3.begin(); it != d3.end(); it++)
    {
        cout << "d3 : " << *it << endl;
    }
    cout << "=====================" << endl;
    
    cout << "d5.size() : " << d5.size() << endl;
    cout << "d5.empty() : " << d5.empty() << endl; 

    d6.clear();
    cout << "d6.empty() : " << d6.empty() << endl;

    d5.resize(1);
    cout << "d5.size() : " << d5.size() << endl;

    d5.resize(5, "欢总别犯困!");
    for (deque<string>::iterator it = d5.begin(); it != d5.end(); it++)
    {
        cout << "d5 : " << *it << endl;
    }
    cout << "---------------------------" << endl;

    return 0;
}

4.4deque大小操作

// 返回容器中元素的个数
deque.size();

// 返回容器是否为空
deque.empty();

// 重新指定容器的长度为 num,若容器变长。则以默认值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除。
deque.resize(num);v

// 重新指定容器的长度为 num,若容器变长,则以 elem 值填充新位置,如果容器变短,则末尾超出容器长度的元素被删除。
deque.resize(num,elem);
// 例子上边

4.5deque双端插入和删除操作

// 在容器尾部添加一个数据
push_back(elem);
// d1.push_back("安阳");

//在容器头部插入一个数据
push_front(elem);

// 删除容器最后一个数据
pop_back();
 
// 删除容器第一个数据
pop_front();
#include <iostream>
#include <string>
#include <deque>

using namespace std;

/*
push_back(elem);// 在容器尾部添加一个数据
push_front(elem);// 在容器头部插入一个数据
pop_back();//删除容器最后一个数据
pop_front();//删除容器第一个数据

at(idx);// 返回索引 idx 所指的数据,如果 idx 越界,抛出 out_of_range

*/
int main(int argc, char const *argv[])
{
    deque<string> d1;
    d1.push_back("安阳");
    d1.push_back("信阳");
    d1.push_back("洛阳");
    d1.push_back("濮阳");
    d1.push_back("原阳");
    d1.push_back("南阳");

    d1.push_front("汝阳");

    for (deque<string>::iterator it = d1.begin(); it != d1.end(); it++)
    {
        cout << "d1 : " << *it << endl;
    }

    cout << "=================" << endl;

    d1.pop_back();
    d1.pop_front();
    for(deque<string>::iterator it = d1.begin();it != d1.end();it++)
    {
        cout << "d1 : " << *it << endl;
    }
    cout << "d1[4]: " << d1[4] << endl;
    cout << "d1.at(4): " << d1.at(4) << endl;

    cout << "d1.front() : " << d1.front() << endl;
    cout << "d1.back() : " << d1.back() << endl;

    return 0;
}

4.6deque数据存取

// 返回索引 idx 所指的数据,如果 idx 越界,抛出 out_of_range;
at(idx); 

// 返回索引 idx 所指的数据,如果 idx 越界,不抛出异常,直接出错。
operator[];

//返回第一个数据
front();

// 返回最后一个数据
back();
//例子见上

4.7deque插入操作

// 在 pos 位置插入一个 elem 元素的拷贝,返回新数据的位置
insert(pos,elem);
// d1.insert(d1.begin() + 5,"周口");

// 在 pos 位置插入 n 个 elem 数据,无返回值
insert(pos,n,elem);
// d1.insert(d1.begin(),2,"郑州");

//在 pos 位置插入[begin,end) 区间的数据,无返回值
insert(pos,beg,end);
//d1.insert(d1.begin() + 3,d2.begin(),d2.end());
#include <iostream>
#include <string>
#include <deque>

using namespace std;

int main(int argc, char const *argv[])
{
    deque<string> d1;

    d1.push_back("安阳");
    d1.push_back("荥阳");
    d1.push_back("信阳");
    d1.push_back("洛阳");
    d1.push_back("濮阳");
    d1.push_back("原阳");
    d1.push_back("南阳");

    d1.insert(d1.begin() + 5,"周口");

    for (deque<string>::iterator it = d1.begin(); it != d1.end(); it++)
    {
        cout << "d1 : " << *it << endl;
    }
    cout << "==============" << endl;

    d1.insert(d1.begin(),2,"郑州");
    for(deque<string>::iterator it = d1.begin();it != d1.end();it++)
    {
        cout << "d1 : " << *it << endl;
    }

    deque<string> d2;
    d2.push_back("云南");
    d2.push_back("南京");
    d2.push_back("长沙");
    // 在 pos 位置插入 begin 到 end 
    d1.insert(d1.begin() + 3,d2.begin(),d2.end());
    for(deque<string>::iterator it = d1.begin();it != d1.end();it++)
    {
        cout << "d1 : " << *it << endl;
    }
    cout << "====================" << endl;

    d2.clear();
    cout << "d2.empty(): " << d2.empty() << endl;

    d1.erase(d1.begin() + 1,d1.begin() + 3);// 删除
    d1.erase(d1.begin() + 7);
    for(deque<string>::iterator it = d1.begin();it != d1.end();it++)
    {
        cout << "d1 : " << *it << endl;
    }
    cout << "=================" << endl;
    
    return 0;
}

4.8deque删除操作

// 移除容器的所有数据
clear();

// 删除[begin,end)区间的数据,返回下一个数据的位置
erase(beg,end);

//删除 pos 位置的数据,返回下一个数据的位置
erase(pos);
//例子见上

5.stack

  • stack 是一种先进后出(Fir In Last Out,FILO)数据结构
  • 不具备迭代器

在这里插入图片描述

5.1stack构造函数

// 采用模板类实现,stack 对象的默认构造形式
stack<T> stkT;

// 拷贝构造函数
stack(const stack &stk);

5.2stack赋值操作

// 重载等号操作符
stack& operator = (const stack &stk);

5.3stack数据存取操作

// 向栈顶添加元素
push(elem);

//从栈顶以处第一个元素
pop();

//返回栈顶元素
top();

5.4 stack大小操作

//判断堆栈是否为空
empty();

// 返回堆栈的大小
size();
// stack 相关函数
#include <iostream>
#include <string>
#include <stack>

using namespace std;

/*
stack<T> stkT; // 采用模板类实现,stack 对象的默认构造函数
stack(const stack &stk);// 拷贝构造函数

stack& operator = (const stack & stk); // 重载等号操作符

push(elem);// 向栈顶添加元素
pop();// 从栈顶移除第一个元素
top();// 返回栈顶元素

empty(); // 判断堆栈是否为空
size();// 返回堆栈的大小
*/
int main(int argc, char const *argv[])
{
    stack<string> st1;

    st1.push("天梭");
    st1.push("美度");
    st1.push("浪琴");
    st1.push("IWC");
    st1.push("欧米伽");
    st1.push("宝珀");
    st1.push("劳力士");
    st1.push("积家");
    st1.push("百达翡丽");

    stack<string> st2 = stack<string>(st1);
    stack<string> st3 = st1;
    
    while (st1.empty() != true)
    {
        cout << st1.top() << endl;
        st1.pop();
    }
    
    cout << "st2.size() : " << st2.size() << endl;
    return 0;
}

6.queue

  • queue 是一种先进先出(First ln First Out,FIFO)的数据结构
  • 不具备迭代器

在这里插入图片描述

6.1queue 构造函数

// queue 采用模板类实现,queue 对象的默认构造形式
queue<T> queT;

// 拷贝构造函数
queue(const queue $que);

6.2queue 存取,插入和删除操作

// 往队尾添加元素
push(elem);

// 从队头移除第一个元素
pop();

// 返回最后一个元素
back();

// 返回第一个元素
front();

6.3queue赋值操作

// 重载等号操作符
queue& operator=(const queue &que);

6.4 queue大小操作

// 判断队列是否为空
empty();
    
// 返回队列的大小
size();
#include <iostream>
#include <queue>
#include <string>

using namespace std;

/*
queue<T> queT;// queue采用
*/
int main(int argc, char const *argv[])
{
    queue<string> q1;

    q1.push("可乐");
    q1.push("崂山白花蛇草水");
    q1.push("格瓦斯");
    q1.push("红色尖叫");
    q1.push("白桃味芬达");
    q1.push("樱桃味可乐");

    cout << "q1.front() : " << q1.front() << endl;
    cout << "q1.back() : " << q1.back() << endl;

    q1.pop();
    cout << "q1.front() : " << q1.front() << endl;

    cout << "q1.size(): " << q1.size() << endl;

    while (q1.empty() != true)
    {
        cout << q1.front() << endl;
        q1.pop();
    }
    

    return 0;
}

7.list【常用】

  • 底层结构是双向有头链表
  • 和 vector 都是常用【容器】
  • 支持迭代器

在这里插入图片描述

7.1list构造函数

// list 采用模板类实现,对象的默认构造形式
list<T> lstT;

// 构造函数将[beg,end)区间中的元素拷贝给本身。
list(beg,end);

// 构造函数将 n 个 elem 拷贝给本身
list(n,elem);

// 拷贝构造函数
list(const list &lst);

7.2list 数据元素插入和删除操作

// 在容器尾部加入一个元素
push_back(elem);

// 删除容器中最后一个元素
pop_back();

// 在容器开头插入一个元素
push_front(elem);

//在容器开头移除第一个元素
pop_front();
#include <iostream>
#include <list>
#include <string>

using namespace std;

int main(int argc, char const *argv[])
{
    list<string> list1;

    list1.push_back("黑森林");
    list1.push_back("半熟芝士");
    list1.push_back("草莓慕斯蛋糕");
    list1.push_back("雪梅娘");
    list1.push_back("榴莲千层");
    list1.push_back("青团");

    list1.push_front("红丝绒蛋糕");

    for (list<string>::iterator it = list1.begin();
         it != list1.end();
         it++)
    {
        cout << "list1 : " << *it << endl;
    }

    cout << "-----------------------------" << endl;

    list<string> list2 = list<string>(++list1.begin(),list1.end());
    for (list<string>::iterator it = list1.begin();
         it != list1.end();
         it++)
    {
        cout << "list2 : " << *it << endl;
    }

    cout << "-----------------------------" << endl;

    list<string> list3 = list<string>(10,"辣椒法棍");
    for (list<string>::iterator it = list1.begin();
         it != list1.end();
         it++)
    {
        cout << "list1 : " << *it << endl;
    }

    cout << "-----------------------------" << endl;
    list<string> list4 = list<string>(list3);
    for (list<string>::iterator it = list1.begin();
         it != list1.end();
         it++)
    {
        cout << "list1 : " << *it << endl;
    }

    cout << "-----------------------------" << endl;
// 在 pos 位置插入 elem 元素的拷贝,返回新数据位置
insert(pos,elem);

// 在 pos 位置插入 n 个 elem 数据,无返回值。
insert(pos,n,elem);

// 在 pos 位置插入[beg,end)区间的数据,无返回值
insert(pos,beg,end);

// 移除容器的所有数据
clear();

// 删除[beg,end)区间的数据,返回下一个数据的位置
erase(beg,end);

//删除 pos位置的数据,返回下一个数据的位置
erase(pos);

//删除容器中所有与 elem 值匹配的元素
remove(elem);
#include <iostream>
#include <list>
#include <string>

using namespace std;

int main(int argc, char const *argv[])
{
    list<string> list1;

    list1.push_back("黑森林");
    list1.push_back("半熟芝士");
    list1.push_back("草莓慕斯蛋糕");
    list1.push_back("雪梅娘");

    list1.insert(++list1.begin(),"蛋挞");
    for (list<string>::iterator it = list1.begin(); it != list1.end(); it++)
    {
        cout << "list1 : " << *it << endl;
    }
    cout << "---------------------" << endl;

    list1.insert(++list1.begin(),5,"鸡蛋糕");
    for (list<string>::iterator it = list1.begin(); it != list1.end(); it++)
    {
        cout << "list1 : " << *it << endl;
    }
    cout << "---------------------" << endl;

    list<string> list2;
    list2.push_back("拿铁咖啡");
    list2.push_back("厚乳咖啡");
    list2.push_back("丝绒拿铁");
    list2.push_back("陨石拿铁");
    list1.insert(list1.begin(),list2.begin(),list2.end());
    for (list<string>::iterator it = list1.begin(); it != list1.end(); it++)
    {
        cout << "list1 : " << *it << endl;
    }
    cout << "---------------------" << endl;


    list2.clear();
    cout << "list2.empty() : " << list2.empty() << endl;
    cout << "--------------------------------" << endl;

    list1.erase(list1.begin(),++list1.begin());
    for (list<string>::iterator it = list1.begin(); it != list1.end(); it++)
    {
        cout << "list1 : " << *it << endl;
    }
    cout << "---------------------" << endl;

    list1.erase(++list1.begin());
    for (list<string>::iterator it = list1.begin(); it != list1.end(); it++)
    {
        cout << "list1 : " << *it << endl;
    }
    cout << "---------------------" << endl;

    list1.remove("鸡蛋糕");
    for (list<string>::iterator it = list1.begin(); it != list1.end(); it++)
    {
        cout << "list1 : " << *it << endl;
    }
    cout << "---------------------" << endl;
    return 0;
}

7.3list大小操作

//返回容器元素的个数
size();

// 判断容器为空
empty();

//重新制定容器的长度为 num ,若容器变长,则以默认值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除
resize(num);

//重新指定容器的长度为 num,若容器变长,则以 elem 值填充新位置,如果容器变短,则末尾超出容器长度的元素被删除。
resize(num.elem);

7.4list赋值操作

// 将[beg,end)区间中的数据拷贝赋值给本身
assign(beg,end);

//将 n 个 elem 拷贝赋值给本身
assign(n,elem);

// 重载等号操作符
list& operator = (const list &lst);

//将 lst 与本身的元素互换
swap(lst);

7.5 list数据的存取

// 返回第一个元素
front(); 

//返回最后一个元素
back();
#include <iostream>
#include <list>
#include <string>

using namespace std;

int main(int argc, char const *argv[])
{
    list<string> list1;

    list1.push_back("黑森林");
    list1.push_back("半熟芝士");
    list1.push_back("草莓慕斯蛋糕");
    list1.push_back("雪梅娘");
    
    cout << "list1.size() : " << list1.size() << endl;

    list1.resize(10,"榴莲千层");
    for (list<string>::iterator it = list1.begin(); it != list1.end(); it++)
    {
        cout << "list1 : " << *it << endl;
    }
    cout << "=====================" << endl;

    list<string> list2;

    list2.push_back("珍珠奶茶");
    list2.push_back("波波奶茶");
    list2.push_back("燕麦奶茶");
    list2.push_back("巧克力奶茶");
    list1.assign(list2.begin(),list2.end());
    for (list<string>::iterator it = list1.begin(); it != list1.end(); it++)
    {
        cout << "list1 : " << *it << endl;
    }
    cout << "=====================" << endl;

    list1.assign(10,"焦糖奶茶");
    for (list<string>::iterator it = list1.begin(); it != list1.end(); it++)
    {
        cout << "list1 : " << *it << endl;
    }
    cout << "=====================" << endl;

    list1.swap(list2);
    for (list<string>::iterator it = list1.begin(); it != list1.end(); it++)
    {
        cout << "list1 : " << *it << endl;
    }
    cout << "=====================" << endl;

    cout << "list1.front() : " << list1.front() << endl;
    cout << "list1.back() : " << list1.back() << endl;
    
    return 0;
}

7.6list反转

// 反转链表,比如 lst 包含 1,3,5 元素,运行此方法后,lst 就包含 5,3,1元素
reverse();

// list排序
sort();
#include <iostream>
#include <string>
#include <list>

using namespace std;

int main(int argc, char const *argv[])
{
    list<int> list1;

    list1.push_back(1);
    list1.push_back(3);
    list1.push_back(5);
    list1.push_back(7);
    list1.push_back(9);
    list1.push_back(2);
    list1.push_back(4);
    list1.push_back(6);
    list1.push_back(8);
    list1.push_back(10);

    /*
    sort 有两个函数
        sort(); [目前使用,默认升序]
        sort(提供排序规则函数对象);
    */
    list1.sort();
    for (list<int>::iterator it = list1.begin(); it != list1.end(); it++)
    {
        cout << "list1 : " << *it << endl;
    }
    cout << "-----------------------" << endl;

    list1.reverse();
    for (list<int>::iterator it = list1.begin(); it != list1.end(); it++)
    {
        cout << "list1 : " << *it << endl;
    }
    cout << "-----------------------" << endl;
    
    return 0;
}

8.set/multiset

8.1概述

set/multiset 底层结构可以认为是平衡二叉树

  • 添加元素有自然顺序或者对应的比较方式
  • 添加元素类型一致
  • 数据会自动排序
  • 数据不允许重复存储

在这里插入图片描述

8.2set构造函数

// 默认构造函数
set<T> st;

//multiset 默认构造函数
mulitset<T> mst;

//拷贝构造函数
set(const set &st);
#include <iostream>
#include <set>
#include <string>

using namespace std;

int main(int argc, char const *argv[])
{
    set<string> st;

    st.insert("BC");
    st.insert("AB");
    st.insert("ABC");
    st.insert("CD");
    st.insert("CE");
    st.insert("CDE");
    st.insert("BCD");
    st.insert("AF");

    set<string>::iterator it = st.begin();

    while (it != st.end())
    {
        cout << "st : " << *it << endl;
        it++;
    }
    cout << "=============================" << endl;

    set<string> st2 = set<string>(st);
    set<string>::iterator it1 = st2.begin();

    while (it1 != st2.end())
    {
        cout << "st2 : " << *it1 << endl;
        it1++;
    }
    
    return 0;
}

8.3set赋值操作

// 重载等号操作符
set&operator=(const set &st);

//交换两个集合容器
swap(st);

8.4set大小操作

// 返回容器中元素的数目
size();

// 判断容器是否为空
empty();

8.5set插入和删除操作

// 在容器中插入元素
insert(elem);
 
// 清楚所有元素
clear();

//删除从 pos 迭代器所指的元素,返回下一个元素的迭代器
erase(pos);

// 删除区间[beg,end)的所有元素,返回下一个元素的迭代器
erase(beg,end);

//删除容器中值为 elem 的元素
erase(elem);
#include <string>
#include <iostream>
#include <set>

using namespace std;

int main(int argc, char const *argv[])
{
    set<string> st1;

    st1.insert("梦雨爱小陈");
    st1.insert("小陈爱梦雨");
    st1.insert("佳丽爱吃");

    set<string> st2 = st1;
    for (set<string>::iterator it = st2.begin(); it != st2.end(); it++)
    {
        cout << "st2 : " << *it << endl;
    }
    cout << "------------------" << endl;

    set<string> st3;
    st3.insert("小陈回家了");
    st3.insert("梦雨哭唧唧");
    st3.insert("哈哈哈哈哈哈哈");

    st2.swap(st3);
    for (set<string>::iterator it = st2.begin(); it != st2.end(); it++)
    {
        cout << "st2 : " << *it << endl;
    }

    st3.clear();
    cout << "---------------------" << endl;

    cout << "st3.size : " << st3.size() << endl;
    cout << "st3.empty : " << st3.empty() << endl;

    cout << "------------------------" << endl;

    set<string>::iterator it = st2.begin();

    st2.erase(it);
    for (set<string>::iterator it = st2.begin(); it != st2.end(); it++)
    {
        cout << "st2 : " << *it << endl;
    }
    cout << "-----------------" << endl;

    st2.insert("嘟嘟嘟");
    st2.insert("嘟嘟嘟1");
    st2.insert("嘟嘟嘟2");
    st2.insert("嘟嘟嘟3");
    st2.insert("嘟嘟嘟4");
    st2.insert("嘟嘟嘟5");

    for (set<string>::iterator it = st2.begin();
         it != st2.end();
         it++)
    {
        cout << "st2 : " << *it << endl;
    }
    cout << "------------------------------" << endl;
    st2.erase(++st2.begin(),--st2.end());

    for (set<string>::iterator it = st2.begin();
         it != st2.end();
         it++)
    {
        cout << "st2 : " << *it << endl;
    }
    cout << "------------------------------" << endl;

    set<int> st4;
    st4.insert(1);
    st4.insert(2);
    st4.insert(3);
    st4.insert(4);
    st4.insert(5);

    st4.erase(5);

    for (set<int>::iterator it = st4.begin();
         it != st4.end();
         it++)
    {
        cout << "st4 : " << *it << endl;
    }
    return 0;
}

8.6set查找操作

// 查找键 key 是否存在,若存在,返回改键的元素的迭代器,若不存在,返回 set.end()
find(key);

// 查找键 key 的元素的个数
cout(key);

// 返回第一个 key>=keyElem 元素的迭代器
lower_bound(keyElem);

// 返回第一个 key>keyElem 元素的迭代器
upper_bound(keyElem);

// 返回容器中key与 keyElem 相等的上下限的两个迭代器(上边两个的整合)
equal_range(keyElem);
#include <iostream>
#include <string>
#include <set>

using namespace std;

int main(int argc, char const *argv[])
{
    set<int> st1;

    st1.insert(1);
    st1.insert(2);
    st1.insert(3);
    st1.insert(4);
    st1.insert(5);
    st1.insert(6);
    st1.insert(7);
    st1.insert(8);
    st1.insert(9);
    st1.insert(10);
    st1.insert(11);
    st1.insert(12);
    st1.insert(13);
    st1.insert(14);
    st1.insert(15);

    set<int>::iterator it1 = st1.find(15);// 查找键是否存在,存在返回该键的元素迭代器,否则返回 最后一个

    cout << "find : " << *it1 << endl;

    cout << "count : " << st1.count(15) << endl;// 查找键 key 的元素个数
    cout << "lower : " << *st1.lower_bound(10) << endl;// 返回第一个 >= key 元素的迭代器
    cout << "upper : " << *st1.upper_bound(10) << endl;// 返回第一个 > key 元素的迭代器

    // 返回容器中 和 键 相等的上下限的两个的迭代器
    // 返回键值对
    pair<set<int>::iterator,set<int>::iterator> p = st1.equal_range(10);

    cout << *p.first << endl;

    cout << *p.second << endl;
    return 0;
}

9.pair对组

9.1概述

对组(pari)将一对值组合成一个值,这一对值可以有不同的数据类型,两个值可以分别用 pair 的两个共有属性 first 和 second 访问 。

类模板:

template<typename T1,typename T2>
struct pair
{
    T1 first;
    T2 second;
}

9.2 获取 pair 对组

pair<T1,T2>(T1 t1,T2,t2);
make_pair(T1 t1,T2 t2);

10.map 键值对

10.1概述

  • map 结构底层存储内容都是pair 对组
  • map 将 pair 第一个数据认为是【键值】,第二个数据认为是【实值】,存储的内容是【键值对内容】
  • map 中 pair 第一个元素,或者说【键值】不可以重复,并且排序规则按照【键值】完成

10.2 map 构造函数

// map 默认构造函数
map<T1,T2> mapTT; 

// 拷贝构造函数
map(const map &mp);

10.3map赋值操作

// 重载等号操作符
map& operator=(const map &mp);

// 交换两个集合容器
swap(mp);

10.4 map 容量函数

// 返回容器中元素的数目
size();

// 判断容器是否为空
empty();

10.5 map 插入数据元素操作


map.insert(...);
// 往容器插入元素,返回pair<iterator,bool>
map<int,string> mapStu;

//第一种 通过 pari 的方式插入对象
mapStu.insert(pair<int,string>(3,"小张"));

// 第二种通过 pari 的方式插入对象
mapstu.insert(make_pair(-1,"小张"));

//第三种通过 value_type 的方式插入对象
mapStu.insert(map<int,string>::value_type(1,"小李"));

//第四种通过 数组 的方式插入值
mapStu[3] = "小刘";
mapStu[5] = "小王";

10.6map删除操作

// 删除所有元素
cleae();

// 删除 pos 迭代器所指的元素,返回下一个元素迭代器
erase(pos);

// 删除区间[beg,end)的所有元素,返回下一个元素的迭代器
erase(beg,end);

// 删除容器中 key 为 keyElem 的对组
erase(keyElem);

10.7map查找操作

// 查找键 key 是否存在,若存在,返回该键的元素的迭代器,若不存在,返回 map.end()
find(key);

// 返回容器中 key 为 keyElem 的对组个数,对 map 来说,要么是 0 ,要么事 1 对 multimap 来说,值可能大于1.
count(keyElem);

//返回第一个 key>=keyElem 元素的迭代器
lower_bound(keyElem);

// 返回第一个 key>keyElem 元素的迭代器
upper_bound(keyElem);

//返回容器中 ke 与 keyElem 相等的上下限的两个迭代器
//上两个的结合
equal_range(keyElem);
  • 38
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值