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 获取

c 复制代码
#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 构造函数

c 复制代码
// 创建一个字符串
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');
c 复制代码
#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 赋值操作

c 复制代码
// 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);
c 复制代码
#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存取字符串操作

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

// 通过 at 方式获取
char& at(int n);// str.at(2)
c 复制代码
#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拼接操作

c 复制代码
// 重载 += 操作符
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);
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 查找和替换

c 复制代码
// 查找 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);
c 复制代码
#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 比较操作

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

// 与字符串 s 比较。
int compare(const char *s) const; 
c 复制代码
#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 子串

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

// 获取字符串有效字符个数
size_t length();
c 复制代码
#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 插入和删除操作

c 复制代码
// 插入字符串
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);
c 复制代码
#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 语言字符串

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

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

3.vector

3.1概述

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

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

3.2 vector构造函数

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

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

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

// 拷贝构造函数
vector(const vector &vec);
c 复制代码
#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 赋值操作

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

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

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

// 将 vec 与本身的元素互换
swap(vec);
c 复制代码
#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大小操作

c 复制代码
// 返回容器中元素的个数
size();

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

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

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

// 容器的容量
capacity();

// 容器预留 len 个元素,预留位置不初始化,元素不可访问
reserve(int len);
c 复制代码
#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数据存取操作

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

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

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

// 返回容器中最后一个数据元素
back();
c 复制代码
#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插入和删除操作

c 复制代码
//迭代器指向位置 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();
c 复制代码
#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 构造函数

c 复制代码
// 默认构造函数
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);
c 复制代码
#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 赋值操作

c 复制代码
// 将[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);
c 复制代码
#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大小操作

c 复制代码
// 返回容器中元素的个数
deque.size();

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

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

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

4.5deque双端插入和删除操作

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

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

// 删除容器最后一个数据
pop_back();
 
// 删除容器第一个数据
pop_front();
c 复制代码
#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数据存取

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

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

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

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

4.7deque插入操作

c 复制代码
// 在 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());
c 复制代码
#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删除操作

c 复制代码
// 移除容器的所有数据
clear();

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

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

5.stack

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

5.1stack构造函数

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

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

5.2stack赋值操作

c 复制代码
// 重载等号操作符
stack& operator = (const stack &stk);

5.3stack数据存取操作

c 复制代码
// 向栈顶添加元素
push(elem);

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

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

5.4 stack大小操作

c 复制代码
//判断堆栈是否为空
empty();

// 返回堆栈的大小
size();
c 复制代码
// 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 构造函数

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

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

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

c 复制代码
// 往队尾添加元素
push(elem);

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

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

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

6.3queue赋值操作

c 复制代码
// 重载等号操作符
queue& operator=(const queue &que);

6.4 queue大小操作

c 复制代码
// 判断队列是否为空
empty();
    
// 返回队列的大小
size();
c 复制代码
#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构造函数

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

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

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

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

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

c 复制代码
// 在容器尾部加入一个元素
push_back(elem);

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

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

//在容器开头移除第一个元素
pop_front();
c 复制代码
#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;
c 复制代码
// 在 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);
c 复制代码
#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大小操作

c 复制代码
//返回容器元素的个数
size();

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

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

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

7.4list赋值操作

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

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

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

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

7.5 list数据的存取

c 复制代码
// 返回第一个元素
front(); 

//返回最后一个元素
back();
c 复制代码
#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反转

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

// list排序
sort();
c 复制代码
#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构造函数

c 复制代码
// 默认构造函数
set<T> st;

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

//拷贝构造函数
set(const set &st);
c 复制代码
#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赋值操作

c 复制代码
// 重载等号操作符
set&operator=(const set &st);

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

8.4set大小操作

c 复制代码
// 返回容器中元素的数目
size();

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

8.5set插入和删除操作

c 复制代码
// 在容器中插入元素
insert(elem);
 
// 清楚所有元素
clear();

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

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

//删除容器中值为 elem 的元素
erase(elem);
c 复制代码
#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查找操作

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

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

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

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

// 返回容器中key与 keyElem 相等的上下限的两个迭代器(上边两个的整合)
equal_range(keyElem);
c 复制代码
#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 访问 。

类模板:

c 复制代码
template<typename T1,typename T2>
struct pair
{
    T1 first;
    T2 second;
}

9.2 获取 pair 对组

c 复制代码
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 构造函数

c 复制代码
// map 默认构造函数
map<T1,T2> mapTT; 

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

10.3map赋值操作

c 复制代码
// 重载等号操作符
map& operator=(const map &mp);

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

10.4 map 容量函数

c 复制代码
// 返回容器中元素的数目
size();

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

10.5 map 插入数据元素操作

c 复制代码
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删除操作

c 复制代码
// 删除所有元素
cleae();

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

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

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

10.7map查找操作

c 复制代码
// 查找键 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);
相关推荐
芊寻(嵌入式)4 分钟前
C转C++学习笔记--基础知识摘录总结
开发语言·c++·笔记·学习
獨枭5 分钟前
C++ 项目中使用 .dll 和 .def 文件的操作指南
c++
霁月风8 分钟前
设计模式——观察者模式
c++·观察者模式·设计模式
橘色的喵9 分钟前
C++编程:避免因编译优化引发的多线程死锁问题
c++·多线程·memory·死锁·内存屏障·内存栅栏·memory barrier
一颗松鼠13 分钟前
JavaScript 闭包是什么?简单到看完就理解!
开发语言·前端·javascript·ecmascript
泉崎13 分钟前
11.7比赛总结
数据结构·算法
有梦想的咸鱼_14 分钟前
go实现并发安全hashtable 拉链法
开发语言·golang·哈希算法
你好helloworld15 分钟前
滑动窗口最大值
数据结构·算法·leetcode
海阔天空_201320 分钟前
Python pyautogui库:自动化操作的强大工具
运维·开发语言·python·青少年编程·自动化
天下皆白_唯我独黑27 分钟前
php 使用qrcode制作二维码图片
开发语言·php