C++中STL库的部分小知识点

一、输入输出

  1. while (cin >> n, n != -1)效果与while (cin >> n && n != -1)相同,表示在输入等于 − 1 -1 1时结束循环;
  2. while (scanf("%d", &n) != EOF)效果与while (cin >> n)相同,在文件到达末尾时会结束循环;
  3. 为实现类似于pythonsplit函数,参见第3.3节;

二、vector

  1. 在类中直接定义vector并初始化时,需要注意一个问题:常用的vector<int> vec(100, 0)这种格式直接放到类下面定义(而不是类函数中定义)时,编译器会把上面那个写法当做了函数定义,可以写作vector<int> vec = vector<int>(100, 0),详见: 类中vector的初始化问题
  2. 二维vector放入新行(数组)时,使用vec.push_back(vector<int>(100, 1)),表示在vec中添加了一个新行,行的长度为100,行中每个元素值为1;
  3. 二维vector数组利用变量初始化行数和列数,并赋初值:
    方法一 vector<vector<int>> matrix(row, vector<int>(colum, value));
    方法二 vector<vector<int>> matrix; matrix.assign(row, vector<int>(colum, value));
  4. 将vector中元素倒序:使用reverse(vec.begin(), vec.end()),若要从某一位置开始,则使用reverse(vec.begin() + pos, vec.end())(包含pos位置)

三、string

  1. 字符串就是字符数组加上结束符'\0',例如使用string s = "C++";得到的大小为3,但是使用char a[] = "C++";得到的长度为4,原因是其结尾会暗含'\0'(即第0个ASCII码),因此char a[] = "C++";等价于char a[] = {'C', '+', '+', '\0'}
  2. cin scanf等输入字符串时遇到空格就会停止,因此要是想把带空格的字符串比如"hello world"一次性输入到字符串变量内,可以使用fgets、getline、cin.getline等函数,但是也有一些注意事项,比如fgets、cin.getline函数会把回车读进去,详见此题的提交记录 760. 字符串长度、以及此题的视频讲解769. 替换字符
  3. python中有一个非常好用的函数叫split,C++中要实现类似的功能可以参考这篇文章C++中string如何实现字符串分割函数split(),相关题目的练习为AcWing 770. 单词替换;此外,一个更优雅的做法是调用sscanf函数,见题636. 函数的独占时间;
  4. 字符串末尾添加字符串为.append(),字符串末尾添加字符为.push_back()
  5. 取子串方法为str.substr(i)表示取 [ i , e n d ) [i, end) [i,end),或者str.substr(i, j)表示取 [ i , i + j ) [i, i + j) [i,i+j),其中 i i i j j j均为索引(下标)而不是迭代器;

四、map

  1. map默认排序方法为按照key值从小到大排序,即map<int, string> Hash等价于map<int, string, less<int>> Hash,若要改为从大到小排序,则可写为map<int, string, greater<int>> Hash
  2. 对map按key值进行自定义排序,例如对于map<string, int> Hash按照字符串长度来排序,则可以使用下面代码:
    struct Compare {
        bool operator()(const string& str1, const string& str2) const { // 注意,此处const不可省略,否则报错
            return str1.size() < str2.size();
        }
    }; 
    
    而后只需在初始化map时写为map<string, int, Compare > Hash即可;
    此外,若map的key值本身就是一个结构体类型或者class类型,则可以直接在定义key值时重载比较运算符,例子如下:
    struct myKeyType {
        int age;
        int score;
        string name;
        bool operator < (myKeyType const& r) const {
            if (score != r.score)  return score < r.score;
            else return age > r.age;
        }
    };
    
    而后只需在初始化map时写为map<myKeyType, int,> Hash即可;
  3. 对map按value值进行自定义排序,一般方法是把map中的键值对放入vector中,再对vector利用sort排序:
    map<string, int> Hash;
    ...
    vector<pair<string, int>> vec(Hash.begin(), Hash.end());
    sort(vec.begin(), vec.end(), [](const pair<string, int>& a, const pair<string, int>& b) {
        return a.second > b.second;
    });
    
  4. 利用迭代器访问map键值对时,iter->first指key值,而iter->second指value值;
  5. map自带upper_bound函数和upper_bound函数,调用为Hash.upper_bound(num)

五、priority_queue

  1. priority_queue默认为大根堆,即priority_queue<int> Q等价于priority_queue<int, vector<int>, less<int>()> Q;而若要使用小根堆,则需要priority_queue<int, vector<int>, greater<int>()> Q;
  2. 自定义排序
    按照second的降序排列
    auto cmp = [](const pair<int, int>& a, const pair<int, int>& b) {
    	return a.second < b.second;
    };
    priority_queue<pair<int, int>, vector<int, int>, decltype(cmp)> que(cmp);
    
    按照first的升序,再按照second的升序排列
    typedef pair<int, int> P;
    struct cmp{
        bool operator()(P a, P b) {
            if(p1.first==p2.first) return p1.second>p2.second;
            else return p1.first > p2.first;
        }
    };
    priority_queue<P, vector<P>, cmp> que;
    

六、class

(1)析构函数

(2) 继承

七、const

  1. const写在函数名前,如const int func(int n)表示此函数的return类型是const类型;
  2. const写在函数名后,如3.2节对map按key值自定义排序,表示此函数是一个常函数,函数中只能作读取操作,而不能作修改操作;
  3. const用在函数参数里,如void func(const int &a),表示该参数在函数体中不能被修改;之所以加了引用符号&是因为一般的形参的值修改并不会影响实参,只有在引用、指针参数、数组参数时才会使用const修饰,详见此两个博客【c++】参数传递—const形参与实参普通引用和const引用区别

八、排序

  1. sort默认为升序排序,如果想要降序,可以使用sort(vec.begin(), vec.end(), greater<int>())
  2. sort自定义排序
    sort(points.begin(), points.end(), [](const vector<int>& a, const vector<int>& b) { return a[2] < b[2]; });
    
    表示对points的行进行排序,排序依据为points的第二列元素的大小;

九、C++特性

(1)运算符重载

(2)lambda函数

(3)捕获

十、常用STL函数

  1. 二分搜索用upper_bound()lower_bound(),前者指大于给定值的第一个迭代器,后者指大于等于给定值的第一个迭代器;而要想将“大于”改为“小于”,或者将“大于等于”改为“小于等于”,则需要在这两个函数的第四个参数位置写上greater<type>() ,详见关于lower_bound( )和upper_bound( )的常见用法
  2. islower()判断是否为小写英文字母, isupper()判断是否为大写英文字母,isdigit()判断是否为数字字符;
  3. max_element(vec.begin(), vec.end())用于返回vec中的最大值迭代器位置(指针);
    • max_element(vec.begin(), vec.end()) - vec.begin()用于返回vec中的最大值索引(下标); *max_element(vec.begin(), vec.end())用于返回vec中的最大值的数值;
    • 此外还能进行自定义比较,比如可以如下定义bool cmp (int a, int b) { return abs(a) < abs(b); },然后将cmp放入max_element第三个参数即可;再或者,可以像sort自定义排序一样借用lambda函数:
    max_element(a.begin(), a.end(), [](const int& a, const int& b){ return abs(a) < abs(b); });
    
  4. 返回数组第 k k k大的元素,可以使用STL库函数中的nth_element(nums.begin(), k, nums.end()),也可以参考快速排序源码思想中的RandomParitition函数所构建出来的RandomSelect函数,详情见《计算机算法设计与分析 第4版 ,王晓东编著 》第2.9章线性时间选择;
  5. 可使用reverse函数将vector元素、string等翻转:reverse(vec.begin(), vec.end()),如果需要从Pos_1位置开始(包括Pos_1位置),则reverse(vec.begin() + Pos_1, vec.end())
  6. accumulate函数包含在#include<numeric>头文件中,能够对vector或数组等中的元素进行求和,其第一、二个参数分别为累加的开始和截止地址,第三个参数为累积初值,一般为0;
    • vector中元素类型为字符串类型时,求和操作就相当于字符串拼接操作,此时第三个参数可以写成""saccumulate(subs.begin(), subs.end(), ""s);,表明累加初值为空字符串;
    • 此外,还可以在第四个参数上写上multiplies<int>(),这样即可实现对vector或数组等中的元素进行连乘,第三个参数为连乘初值。
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值