类的使用方法(一):C++之STL

这段时间刷leetcode发现自己对很多常用的类很不熟悉,有时某些操作忘记了还要到网上去找,很多博客整理的很不全,这里我做个小结,也方便自己以后查阅。

一、常用类

这里主要介绍几个在leetcode中经常用到的类:

  • vector
  • string
  • set
  • map
  • queue
  • stack

使用之前都要声明各自的头文件,并使用std域名,如果不使用std域名,则每次定义变量之前要在使用的类之前加上域名std。

(一)vector

大小可变的数组,支持快速随机访问,在尾部插入或者删除元素速度很快,其余位置的插入或者删除较慢。

声明:

vector<template> v_name;

这里的template需要替换:

  • 某种特定的数据类型,比如:int、double、long等。
  • 也可以是自己定义的结构体
  • 也可以是某些类,比如:vector、queue等。

1、push_back

vector<int> nums;
nums.push_back(1);

将数据存放到vector的末尾,vector的长度+1。

2、pop_back

括号内不需要参数

删除数组的末尾元素,没有返回值(void)

vector<int> nums;
nums.push_back(1);
nums.pop_back();

3、erase

这个操作有2种使用方法:

  • 删除单独的某个元素
    vector<int> nums;
    for(int i=0; i < 20; i++)
        nums.push_back(i);
  
    nums.erase(nums.begin() + 10);

注意,这里必须使用迭代器与偏移的形式来指明需要删除的元素。
上面的例子中,删除nums[10]也就是数组中的第11个元素,而不是第10个。

  • 批量删除连续的元素
    vector<int> nums;
    for(int i=0; i < 20; i++)
        nums.push_back(i);
    
    nums.erase(nums.begin(), nums.begin() + 10);

批量删除也需要写成迭代器与偏移的形式
这个例子中删除nums[0]到nums[10]之间的所有元素,包括nums[0],但是不包括nums[10],一共是10个元素,这里顺便说一下大部分的区间规则都是左闭右开的。

4、insert

这个操作有3种用法:

(1)插入单个元素
    vector<int> nums;
    for(int i=0; i < 20; i++)
        nums.push_back(i);
    
    int j = 10;
    nums.insert(nums.begin() + 2, j);

将j元素插入到nums[2]的位置,nums[2]原来的元素移动到nums[3],依次类推。

(2)批量插入多个相同元素
    vector<int> nums;
    for(int i=0; i < 20; i++)
        nums.push_back(i);
    
    nums.insert(nums.begin() + 2, 6, 100);

三个参数:

  • 迭代器,指定插入的第一个位置
  • 整数,指定插入元素的数量
  • 需要插入的data

上面的例子,从nums[2]的位置开始,插入6个100。

(3)从其他同类型的vector中,批量插入元素
    vector<int> nums;
    for(int i=0; i < 20; i++)
        nums.push_back(i);
    vector<int> temp;
    for(int i=30; i < 40; i++)
        temp.push_back(i);
    int j = 10;
    
    nums.insert(nums.begin() + 2, temp.begin(), temp.begin() + 7);

三个参数:

  • 迭代器,指定插入的第一个位置
  • 迭代器,选定批量元素的起始位置
  • 迭代器,选定批量元素的结束位置(不包括这个迭代器)

这个例子中,插入的是30~36(不包括temp.begin() + 7),共计7个元素。
这里也是左闭右开

5、使用algorithm头文件实现常用操作

(1)sort

排序操作
这个操作需要algorithm头文件,可升序可降序,一般用于数字和字符串排序

  • 升序
#include<vector>
#include<algorithm>
using namespace std;

    vector<int> nums;
    for(int i=20; i >= 0; i--)
        nums.push_back(i);
    sort(nums.begin(), nums.end());
  • 降序
    使用反向迭代器就能实现降序排序了
    反向迭代器,正如其名:
    rbegin() = end()
    rend() = begin()
#include<vector>
#include<algorithm>
using namespace std;

    vector<int> nums;
    for(int i=0; i < 20; i++)
        nums.push_back(i);
    sort(nums.rbegin(), nums.rend());

另外,你们可能也注意到了,凡是使用到了迭代器的地方,都可以加偏移来实现vector内部分排序,比如:

sort(nums.begin() + 1, nums.begin() + 10);

注:我在网上看过很多写比较函数,来实现结构体或者类排序的,但是我写出来的VSCode没有报错,一运行就出问题,找不出原因。如果有知道怎么写的大神,欢迎在评论区指明。

(2)find

查找操作

#include<vector>
#include<algorithm>
using namespace std;

    vector<int> nums;
    for(int i=0; i < 20; i++)
        nums.push_back(i);

    auto n = find(nums.begin(), nums.end(), 5);

三个参数:

  • 迭代器,查找的起始位置
  • 迭代器,查找的终止位置(不在查找范围内)
  • 需要查找的数据

返回:
找到了,则返回找到元素的迭代器
没有找到,返回第二个迭代器(即:查找的终止位置)

注:很多时候,如果不知道要返回什么,直接写auto,可以自动匹配数据类型。

(3)reverse

反转vector,这个有时候会用,自己动手写也很快

    vector<int> nums;
    for(int i=0; i < 20; i++)
        nums.push_back(i);

    reverse(nums.begin(), nums.end());

也可以部分反转,改一改迭代器就行。

(二)string

与vector相似的容器,但专门用于保存字符。

基础:

  • 字符串声明:
    string s1();          // si = ""
    string s2("Hello");   // s2 = "Hello"
    string s3(4, 'K');    // s3 = "KKKK"
    string s4("12345", 1, 3);  //s4 = "234",即 "12345" 的从下标 1 开始,长度为 3 的子串
  • 字符串赋值:

可以用 char* 类型的变量、常量,以及 char 类型的变量、常量对 string 对象进行赋值。

    string s5, s6;
    s5 = "Hello";  // s5 = "Hello"
    s6 = 'K';      // s6 = "K”
  • 字符串连接
    string s7 = s5 + s6;    //s7 = "HelloK"

或者:

    string s8("123"), s9("abc");
    s8.append(s9);              // s8 = "123abc"
    s8.append(s9, 1, 2);        // s8 = "123abcbc"
    s8.append(3, 'K');          // s8 = "123abcbcKKK"
    s8.append("ABCDE", 2, 3);   // s8 = "123abcbcKKKCDE",添加 "ABCDE" 的子串(2, 3):"CDE"
  • 字符串修改
    string s7 = s5 + s6;    //s7 = "HelloK"
    s7[0] = 'w';            //s7 = "welloK"

1、compare

除了可以用 <、<=、==、!=、>=、> 运算符比较 string 对象外,string 类还有 compare 成员函数,可用于比较字符串。

compare 成员函数有以下返回值:

  • 小于 0 表示当前的字符串小;
  • 等于 0 表示两个字符串相等;
  • 大于 0 表示另一个字符串小。
    string s1("hello"), s2("hello, world");
    int n = s1.compare(s2);          // 比较s1与s2
    n = s1.compare(1, 2, s2, 0, 3);  // 比较s1的子串 (1,2) 和s2的子串 (0,3)
    n = s1.compare(0, 2, s2);        // 比较s1的子串 (0,2) 和 s2
    n = s1.compare("Hello");         // 比较s1与“Hello”
    n = s1.compare(1, 2, "Hello");        //比较 s1 的子串(1,2)和"Hello”
    n = s1.compare(1, 2, "Hello", 1, 2);  //比较 s1 的子串(1,2)和 "Hello" 的子串(1,2)

compare操作实际上是将两个字符串逐个字符的ASCII值相减,直到出现第一个不为0的字符或者其中一个字符串结束(注:当字符串结束后,之后的字符的ASCII视为0)

2、substr

求 string 对象的子串。

    string s1 = "this is ok";
    string s2 = s1.substr(2, 4);  // s2 = "is i":    s1[2]('i')开始往后的4个字符组成的字符串
    s2 = s1.substr(2);            // s2 = "is is ok":s1[2]('i')开始往后直到结束的字符组成的字符串

3、swap

交换两个字符串的内容。

    string s1("West"), s2("East");      // s1 = "West",s2 = "East"
    s1.swap(s2);                        // s1 = "East",s2 = "West"
    错误的写法:
    s1.swap("hello");

4、查找操作

string 类有一些查找子串和字符的成员函数。

  • 它们的返回值都是子串或字符在 string 对象字符串中的位置(即下标)。
  • 如果查不到,则返回 string::npos。

string: :npos 是在 string 类中定义的一个静态常量。这些函数如下:

(1)find

从前往后查找子串或字符出现的位置。

  • 查找字符
    string s1("Source Code");
    int n;
    if ((n = s1.find('u')) != string::npos) 
        //查找 u 出现的位置
        cout << "1:    " << n << "," << s1.substr(n) << endl;
        //输出 1:   2,urce Code
  • 指定查找的开始位置
    string s1("Source Code");
    int n;
    if ((n = s1.find("Source", 3)) == string::npos)
        //从下标3开始查找"Source",找不到
        cout << "2:    " << "Not Found" << endl;  
        //输出 2:    Not Found
  • 查找字符串
    string s1("Source Code");
    int n;
    if ((n = s1.find("Co")) != string::npos)
        //查找子串"Co"。能找到,返回"Co"的位置
        cout << "3:    " << n << ", " << s1.substr(n) << endl;
        //输出 3:    7, Code
(2)rfind

从后往前查找子串或字符出现的位置。

    string s1("Source Code");
    int n;
    if ((n = s1.rfind('u')) != string::npos) 
        //查找 u 出现的位置
        cout << "1:    " << n << "," << s1.substr(n) << endl;
        //输出 1:   2,urce Code
(3)find_first_of

从前往后查找何处出现另一个字符串中包含的字符(可以指定开始查找的位置)。

    string s1("Source Code");
    int n;
    if ((n = s1.find_first_of("ceo")) != string::npos)
        //查找第一次出现或 'c'、'e'或'o'的位置
        cout << "4:    " << n << ", " << s1.substr(n) << endl;
        //输出 4:    l, ource Code
(4)find_last_of

从后往前查找何处出现另一个字符串中包含的字符(可以指定开始查找的位置)。

    string s1("Source Code");
    int n;
    if ((n = s1.find_last_of('e')) != string::npos)
        //查找最后一个 'e' 的位置
        cout << "5:    " << n << ", " << s1.substr(n) << endl;  
        //输出 5:    10, e
(5)find_first_not_of

从前往后查找何处出现另一个字符串中没有包含的字符(可以指定开始查找的位置)。

    string s1("Source Code");
    int n;
    if ((n = s1.find_first_not_of("eou", 1)) != string::npos)
        // 从下标1开始查找第一次出现非 'e'、'o' 或 'u' 字符的位置
        cout << "6:    " << n << ", " << s1.substr(n) << endl;
        //输出 6:    3, rce Code
(6)find_last_not_of

从后往前查找何处出现另一个字符串中没有包含的字符(可以指定开始查找的位置)。

    string s1("Source Code");
    int n;
    if ((n = s1.find_last_not_of("eou", 1)) != string::npos)
        //从下标1开始查找第一次出现非 'e'、'o' 或 'u' 字符的位置
        cout << "6:    " << n << ", " << s1.substr(n) << endl;
        //输出 6:    0, Source Code

5、erase

删除指定位置的字符或者字符串

string s1("Real Steel");
s1.erase(1, 3);   //删除子串(1, 3)“eal”,此后 s1 = "R Steel"
s1.erase(5);      //删除下标5及其后面的所有字符,此后 s1 = "R Ste"

6、insert

insert 成员函数可以在 string 对象中插入另一个字符串,返回值为对象自身的引用。

string s1("Limitless"), s2("00");
s1.insert(2, "123");      //在下标 2 处(s1[2]='m')插入字符串"123",s1 = "Li123mitless"
s1.insert(3, s2);         //在下标 3 处(s1[3]='2')插入 s2 , s1 = "Li10023mitless"
s1.insert(3, 5, 'X');     //在下标 3 处(s1[3]='0')插入 5 个 'X',s1 = "Li1XXXXX0023mitless"

(三)set

set是使用红黑树实现的一个容器,具有自动去重的功能。

1、insert

    set<int> list;
    for(int i=0; i < 10; i++)
        list.insert(i);

2、erase

删除操作,这个操作根据里面的key value来决定删除哪一个元素(set与vector不同,本身没有顺序)

    set<int> list;
    for(int i=0; i < 100; i++)
        list.insert(i);
    
    list.erase(5);

3、count

统计其中某一key value的数量,因为set具有自动去重的功能,所以返回值要么是0,要么是1.

    set<int> list;
    for(int i=0; i < 100; i++)
        list.insert(i);
    
    list.count(5);

4、lower_bound(val)

返回某个key value不小于val的迭代器,通过*来访问该key value

    set<int> list;
    for(int i=0; i < 100; i++)
        list.insert(i);
    
    auto temp = list.lower_bound(5);
    cout << *temp;
    // 输出: 5

5、upper_bound(val)

返回某个key value大于val的迭代器,通过*来访问该key value

    set<int> list;
    for(int i=0; i < 100; i++)
        list.insert(i);
    
    auto temp = list.upper_bound(5);
    cout << *temp;
    // 输出: 6

6、clear

删除set里面的所有数据

(四)map

映射,这是一个很有用的容器。

声明

map<template1, template2> name;

通过映射可以将两种不同或相同的数据联系起来

比如:将字符串映射为数字

map<string, int> str2int;

1、insert

    map<string, int> str2int;
    str2int.insert(map<string, int>::value_type("hello", 5));
    cout << str2int["hello"];
    // 输出 5

注意:不能重复映射。

举个例子:

    map<string, int> str2int;
    str2int.insert(map<string, int>::value_type("hello", 5));
    str2int.insert(map<string, int>::value_type("hello", 50));
    cout << str2int["hello"];
    // 输出 5
    这里输出的还是5,不是50,如果要修改映射为50,则:
    str2int["hello"] = 50;

2、count

查找其中某个key value出现的次数,并返回该次数,由于不能重复映射,最多为1

    map<string, int> str2int;
    str2int.insert(map<string, int>::value_type("hello", 5));
    cout << str2int.count("hello");

3、find

查找函数,找出某个key value,并返回该迭代器

    map<string, int> str2int;
    str2int.insert(map<string, int>::value_type("hello", 5));
    auto f = str2int.find("hello");
    cout << f->first << "    " << f->second;
    // 输出 hello    5

4、erase

删除,有两种方法:

  • 按迭代器删除
    map<string, int> str2int;
    str2int.insert(map<string, int>::value_type("hello", 5));
    auto f = str2int.find("hello");
    str2int.erase(f);
  • 按key value删除
    map<string, int> str2int;
    str2int.insert(map<string, int>::value_type("hello", 5));
    auto f = str2int.find("hello");
    str2int.erase("hello");

5、lower_bound(val)

返回 key value >= val 的第一个位置

    map<int, string> int2str;
    int2str.insert(map<int, string>::value_type(5, "hello"));
    auto f = int2str.lower_bound(5);
    cout<< f->first << "   " << f->second;
    // 输出: 5   hello

6、upper_bound(val)

返回 key value >= val 的第一个位置

    map<int, string> int2str;
    int2str.insert(map<int, string>::value_type(5, "hello"));
    auto f = int2str.lower_bound(9);
    if(f == int2str.end())
        cout << "not found";
    else
        cout<< f->first << "   " << f->second;
    // 输出 not found
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值