C++编程的小技巧
前言
坚持了这么多天编写代码,仍会时长出现一些被忽略的一些小细节,经常是百度一下或者回看之前的笔记,到最后还是忘记了。虽说大行不顾细谨,大礼不辞小让,但是真正到了编程的考场,到时候慌的就是自己了,为了让自己没有那么慌张,特此专门撰写了这篇有关C++小技巧的文章,注意是C++小技巧哦,下面就开始吧~
1. 有关头文件
1.1 C语言的stdio.h
相信大家熟悉了C++的代码编写,头文件信手拈来,#include<iostream> using namespace std;
但是#include<stdio.h>
可是不能忘记的,因为在代码编写的的时候,比如遇到输出,限定了位数,如果记不住 C++的cout << setiosflags(ios::fixed) << setprecision(len);
(其中len是保留的位数,之后的cout就是对应的位数了),那么就只能printf("%.lenf", num)
(len是保留的位数),要是忘记了头文件,那可就GG了,唯一的捷径也给你锁死了。。。
1.2 其他头文件
#include<algorithm>
:很常见的头文件,通常有min(),max(),reverse(),sort()函数,可以随取随用。
#include<vector>
:这个就不解释了,熟悉 LeetCode的朋友都会用。
#include<map>
:使用map,存储key、value的关系。
#include<queue>
:队列的定义,BFS中常用。
1.3 只用记住一个的头文件
真的不是噱头,真的有这么个头文件,记住它其它的头文件记不住也没关系,当然你的编译器要支持才行,那就是#include<bits/stdc++.h>
!这个头文件真的无敌,直接用就完事,其他头文件想都不用想,就是编译时间稍长些。
2. STL的相关操作
STL是编程中最常用的伙伴,尤其是LeetCode中,但是可别忘了,LeetCode可以使用auto这个大杀器,那可是百试不厌,什么对map的遍历,直接如下:
for(auto& [a, b] : nums) {
//...
}
但是很多编译器是不支持auto的,还是老老实实的用迭代器吧,下面是对map的一个使用的介绍。
2.1 Map的使用
首先就介绍一下map通过迭代器的遍历吧,如下所示:
map<int, int> mp;
map<int, int>:: iterator it;
for(it = mp.begin(); it != mp.end(); it ++) {
//...
}
下面还有一些其他map使用的介绍,这里也列举出来:
// 插入
mp[1] = 1;
mp.insert(pair<int, int>(1, 1));
// 通过迭代器删除
it = mp.begin();
mp.erase(it);
// 通过key删除
int a = 1;
mp.erase(1);
// Map的全部删除
mp.erase(mp.begin(), mp.end());
// 输出key,value
cout << it -> first << " " << it -> second;
// 查找key==1的数量(value得是int型)
mp.count(1)
// 查找key是否存在
if(mp.find(1) != mp.end()) {
cout << 1;
}
2.2 队列的使用
在BFS问题中,queue是最常用的数据结构了,queue的使用不像map那么复杂,一般是取出一个数,出队列,再入队列,通常会用到如下的函数:
queue<int> q; // 定义队列
q.push(1); // 装入1
q.pop(); // 出队列
int a = q.front(); // 取首元素
// 空退出,非空继续循环
while(!q.empty()) {
//...
}
q.size() // 队列的长度
q.back() // 队列的最后一个元素
2.3 vector的使用
vector是最常见的STL了,常见的操作如下:
(1)a.assign(b.begin(), b.begin()+3); //b为向量,将b的0~2个元素构成的向量赋给a
(2)a.assign(4,2); //是a只含4个元素,且每个元素为2
(3)a.back(); //返回a的最后一个元素
(4)a.front(); //返回a的第一个元素
(5)a[i]; //返回a的第i个元素,当且仅当a[i]存在2013-12-07
(6)a.clear(); //清空a中的元素
(7)a.empty(); //判断a是否为空,空则返回ture,不空则返回false
(8)a.pop_back(); //删除a向量的最后一个元素
(9)a.erase(a.begin()+1,a.begin()+3); //删除a中第1个(从第0个算起)到第2个元素,也就是说删除的元素从a.begin()+1算起(包括它)一直到a.begin()+ 3(不包括它)
(10)a.push_back(5); //在a的最后一个向量后插入一个元素,其值为5
(11)a.insert(a.begin()+1,5); //在a的第1个元素(从第0个算起)的位置插入数值5,如a为1,2,3,4,插入元素后为1,5,2,3,4
(12)a.insert(a.begin()+1,3,5); //在a的第1个元素(从第0个算起)的位置插入3个数,其值都为5
(13)a.insert(a.begin()+1,b+3,b+6); //b为数组,在a的第1个元素(从第0个算起)的位置插入b的第3个元素到第5个元素(不包括b+6),如b为1,2,3,4,5,9,8 ,插入元素后为1,4,5,9,2,3,4,5,9,8
(14)a.size(); //返回a中元素的个数;
(15)a.capacity(); //返回a在内存中总共可以容纳的元素个数
(16)a.resize(10); //将a的现有元素个数调至10个,多则删,少则补,其值随机
(17)a.resize(10,2); //将a的现有元素个数调至10个,多则删,少则补,其值为2
(18)a.reserve(100); //将a的容量(capacity)扩充至100,也就是说现在测试a.capacity();的时候返回值是100.这种操作只有在需要给a添加大量数据的时候才 显得有意义,因为这将避免内存多次容量扩充操作(当a的容量不足时电脑会自动扩容,当然这必然降低性能)
(19)a.swap(b); //b为向量,将a中的元素和b中的元素进行整体性交换
(20)a==b; //b为向量,向量的比较操作还有!=,>=,<=,>,<
(21)vector<int> res;
accumulate(res.begin(), res.end(), 0); // 求和
3. 常见细节
3.1 小数点输出
前面有所提及,这里单独说明是为了强调,一共有两种形式,一个是使用C语言的形式,一种就是提前限制输出位置,代码如下:
double a = 1.4234234;
cout << setiosflags(ios::fixed) << setprecision(2);
cout << a << endl; // 这个时候输出的就是1.42
printf("%.2f", a); // 这种方法也可以输出两位小数
3.2 数组的初始化
对于vector数组来说,比如vector<int> res
,一般的初始化为res.resize(10, 1);
或者是a.assign(b.begin(), b.end());
但是正常定义的数组也有很多初始化方法,如下所示:
int a[10] = {1}; // 赋值初始化
// 给静态数组赋初值,注意参数位置
memset(a, 0, a.size());
// 给静态数组赋初值,注意参数位置
fill(a, a + a.size(), 0);
4. 总结
以上只是我一时想出来有关C++的需要总结的地方,当然会在日后的做题中进行更新迭代,也希望读者可以私信或者评价,指出其他需要注意的地方,万分感谢!