在各大OJ
或者leetcode
刷题时,会不可避免地用到很多很多STL容器或者STL中的常用算法,然而有一些自己用的不熟的经常会在比赛时突然忘掉它的用法,参数,返回类型等,今天就来总结一下这些常用的能令我们解题过程事半功倍的函数!
short is better:能用递归的一定不用栈,能用STL的一定不要自己实现!
下面开始了!
函数原型:sort(起始地址, 末尾地址, cmp)
,其中cmp
是可以自己定义的函数名.
#include
using namespace std;
int main(){
int a[5] = {5,2,3,9,1};
sort(a, a + 5);
for(int i = 0; i < 5; i++) cout << a[i] << ' ';
cout << endl;
return 0;
}
输出为:1 2 3 5 9
#include
using namespace std;
int main(){
vector vec = {5,2,3,9,1};
sort(vec.begin(), vec.end());
for(int v : vec) cout << v << ' ';
cout << endl;
return 0;
}
输出为:1 2 3 5 9
cmp
示例(也可对结构体排序使用)#include
using namespace std;
bool cmp(int &a, int &b){
return a > b;
}
int main(){
vector vec = {5,2,3,9,1};
sort(vec.begin(), vec.end(), cmp);
for(int v : vec) cout << v << ' ';
cout << endl;
return 0;
}
输出为:9 5 3 2 1
函数原型:reverse(起始地址, 末尾地址);
vector示例(数组同上):
#include
using namespace std;
int main(){
vector vec = {5,2,3,9,1};
reverse(vec.begin(), vec.end());
for(int v : vec) cout << v << ' ';
cout << endl;
return 0;
}
输出为:1 9 3 2 5
函数原型:unique(起始地址, 末尾地址, fun);
其中fun为自定义的函数名。
注意:unique函数去重并不是真正的去重,它是不断的将后面不重复的元素覆盖前面重复的元素,最后返回最后一个不重复的元素的地址。下面来看看示例:
#include
using namespace std;
int main(){
vector vec = {1,1,2,3,3,4,4,5};
auto pos = unique(vec.begin(), vec.end()) - vec.begin();
//打印输出使用了unique函数后的vec
for(int i : vec) cout << i << ' ';
cout << endl << "最后一个不重复的元素是:" << pos << endl;
return 0;
}
输出为:
1 2 3 4 5 4 4 5
最后一个不重复的元素是:5
可以看出用了unique()
函数并不能真正将vec
去重,那么要如何做才能真正去重呢?
答案是用erase()
方法,请看示例:
#include
using namespace std;
int main(){
vector vec = {1,1,2,3,3,4,4,5};
auto pos = unique(vec.begin(), vec.end());
vec.erase(pos, vec.end());
for(int v : vec) cout << v << ' ';
cout << endl;
return 0;
}
输出为:1 2 3 4 5
知道了这个去重函数后,leetcode
上的Remove Duplicates from Sorted Array就可以秒解了!
题目描述:Given a sorted array nums, remove the duplicates in-place such that each element appears only once and returns the new length.
Do not allocate extra space for another array, you must do this by modifying the input array in-place with O(1) extra memory.
样例:
Example 1:
Input: nums = [1,1,2]
Output: 2, nums = [1,2]
Explanation: Your function should return length = 2, with the first two elements of nums being 1 and 2 respectively. It doesn't matter what you leave beyond the returned length.
Example 2:
Input: nums = [0,0,1,1,1,2,2,3,3,4]
Output: 5, nums = [0,1,2,3,4]
Explanation: Your function should return length = 5, with the first five elements of nums being modified to 0, 1, 2, 3, and 4 respectively. It doesn't matter what values are set beyond the returned length.
AC code:
class Solution {
public:
int removeDuplicates(vector& nums) {
nums.erase(unique(nums.begin(), nums.end()), nums.end());
return nums.size();
}
};
lower_bound(起始地址, 末尾地址, target)
:查找第一个大于等于target目标值的位置
upper_bound(起始地址, 末尾地址, target)
:查找第一个大于target目标值的位置
binary_search(起始地址, 末尾地址, target)
:查找target是否存在于数组或vector中,找到返回true,否则返回false
这三种方法都是采用的二分查找实现的函数,用于有序数组或vector等,查找效率较高,实际写题时,直接用能较少很多代码量。下面来看看示例吧:
#include
using namespace std;
int main(){
vector vec = {1,1,2,3,3,4,4,5};
auto pos1 = lower_bound(vec.begin(), vec.end(), 2) - vec.begin();
auto pos2 = upper_bound(vec.begin(), vec.end(), 2) - vec.begin();
auto flag = binary_search(vec.begin(), vec.end(), 2);
cout << "第一个大于等于2的位置是" << pos1 << endl;
cout << "第一个大于2的位置是" << pos2 << endl;
cout << "查找2返回的结果:" << flag << endl;
return 0;
}
输出如下:
第一个大于等于2的位置是2
第一个大于2的位置是3
查找2返回的结果:1
s1.find(s2)
:在s1字符串中查找s2,查找到返回第一个字符的位置,查找失败返回s1.npos
,这个其实是一个特别标志,也可以看成一个数字,是4294967295,即s1.npos=4294967295
看看示例:
#include
using namespace std;
int main(){
string s = "abcdabef";
cout << s.find('b') << endl;
cout << s.find("ab") << endl;
cout << s.find("cda") << endl;
cout << s.find("cde") << endl;
return 0;
}
输出如下:
1
0
2
4294967295
set.find(a)
:查找a是否在set中,如果找不到,返回set.end()
set.count(a)
:本来是计算a出现的次数,但是由于集合中是没有重复元素的,于是count函数也就被作为查找函数了,因为a只能出现1次或者0次,查找成功,返回1;查找失败返回0.
示例:
#include
using namespace std;
int main(){
vector v = {1,2,3,4};
set s(v.begin(), v.end());
//查找2
if (s.find(2) != s.end()) cout << "查找成功" << endl;
else cout << "查找失败" << endl;
return 0;
}
输出为:查找成功
map.find()
:主要用于查找key是否存在map中,不存在返回map.end()
,用法和set一样
stoi(s)
:将字符串s转化成整形,s为string
类型,即string --> int
atoi(s)
:将字符串转化为整形,但s为const char*
类型,可以先用s.c_str()
方法把string
类型转化为const char*
类型,再转为整形,即const char --> int
stringstream
:需要头文件#include
,可将只含数字的字符串转化为整形,也可将数字和小数点组成的字符串转化为浮点型,即string --> int, string --> double
示例:
#include
using namespace std;
int main(){
string s = "124";
int a = stoi(s);//s -> a
s = "123.4";
double x;
stringstream ss;
ss << s;
ss >> x;
cout << a << endl;
cout << x << endl;
return 0;
}
输出如下:
124
123.4
stringstream
:需要头文件#include
,可将整形或浮点型数字转化为字符串,即int --> string, double --> string
to_string()
:可将整形转化为字符串,不推荐将浮点型转化为字符串示例:
#include
using namespace std;
int main(){
double x = 12.34;
int y = 12;
stringstream ss;
string s;
ss << x;
ss >> s;
cout << s << endl;
s = to_string(y);
cout << s << endl;
return 0;
}
输出如下:
12.34
12
欢迎大家评论补充呀!