#include <algorithm>
reverse
适用于vector或数组
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
const int N = 1010;
int main(){
// vector
vector<int> c({1, 2, 3, 4, 5});
reverse(c.begin(), c.end());
for(int x : c) cout << x << " "; // 5 4 3 2 1
cout << endl;
// 数组
int a[] = {1, 2, 3, 4, 5};
reverse(a, a + 5);
for(int x : a ) cout << x << " "; // 5 4 3 2 1
cout << endl;
return 0;
}
unique
同样适用于数组与vector
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
const int N = 1010;
int main(){
int a[] = {1, 1, 2, 2, 3, 3, 4};
int m = unique(a, a + 7) - a; // unique()返回去重数组最后一个元素的下一个位置
cout << m << endl; // 4 剩下的不重复元素的数目
for(int i = 0; i < m; i ++ ) cout << a[i] << " ";
cout << endl; // 1 2 3 4
for(int i = 0; i < 7; i ++ ) cout << a[i] << " ";
cout << endl; // 1 2 3 4 3 3 4
return 0;
}
对于vector
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
const int N = 1010;
int main(){
vector<int> a = {1, 1, 2, 2, 3, 3, 4};
int m = unique(a.begin(), a.end()) - a.begin(); // unique()返回去重数组最后一个元素的下一个位置
cout << m << endl; // 4 剩下的不重复元素的数目
cout << a.size() << endl;
for(int i = 0; i < m; i ++ ) cout << a[i] << " "; // 1 2 3 4
cout << endl;
for(int i = 0; i < a.size(); i ++ ) cout << a[i] << " "; // 1 2 3 4 3 3 4
cout << endl;
return 0;
}
因此可以看到unique()为原地操作,只是将不重复元素放在前面,并不删除后面元素。而对于vector,其erase()可删除后面的多余元素。
erase
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
const int N = 1010;
int main(){
vector<int> a({1, 1, 2, 2, 3, 3, 4});
// 从排序维护好的数组的end()到原数组的end()都去掉,正好得去重数组
a.erase(unique(a.begin(), a.end()), a.end());
for(auto x : a) cout << x << " ";
cout << endl; // 1 2 3 4
return 0;
}
random_shuffle
#include <iostream>
#include <algorithm>
#include <vector>
#include <ctime>
using namespace std;
const int N = 1010;
int main(){
vector<int> a({1, 2, 3, 4, 5});
// 1970年1月1日到现在的秒数 随机种子
srand(time(0));
random_shuffle(a.begin(), a.end());
for(int x : a) cout << x << " " ; // 每次运行不同
cout << endl;
return 0;
}
lower_bound、upper_bound
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
int main(){
// lower_bound、upper_bound用于数组/vector,且数组/vector为有序,用二分实现
// lower_bound(起始位置, 结束位置, 比较的数) 返回第一个大于等于该数的数的地址或迭代器
// upper_bound(起始位置, 结束位置, 比较的数) 返回第一个严格大于该数的数的地址或迭代器
// 数组
// int a[] = {1, 2, 4, 5, 6};
// int* p = lower_bound(a, a + 5, 4); // 返回地址,第一个大于等于4的数的地址
// cout << *p << endl; // 4
// int t = lower_bound(a, a + 5, 4) - a; // 相减得下标,第一个大于等于4的数的下标
// cout << t << endl; // 2
// int* pp = upper_bound(a, a + 5, 4); // 严格大于
// cout << *pp << endl; // 5
// int tt = upper_bound(a, a + 5, 4) - a; // 严格大于
// cout << tt << endl; // 3
// vector
// vector<int> a({1, 2, 4, 5, 6});
vector<int> a = {1, 2, 4, 5, 6};
vector<int>::iterator p = lower_bound(a.begin(), a.end(), 4); // 返回地址,第一个大于等于4的数的地址
cout << *p << endl; // 4
int t = lower_bound(a.begin(), a.end(), 4) - a.begin(); // 相减得下标,第一个大于等于4的数的下标
cout << t << endl; // 2
cout << a[t] << endl; // 4
vector<int>::iterator pp = upper_bound(a.begin(), a.end(), 4); // 严格大于
cout << *pp << endl; // 5
int tt = upper_bound(a.begin(), a.end(), 4) - a.begin(); // 相减得下标,第一个大于等于4的数的下标
cout << tt << endl; // 3
cout << a[tt] << endl; // 5
return 0;
}
nth_element()
用法简介:
只支持随机访问迭代器,用于数组、vector、deque。
nth_element(起始位置l,位置i,结束位置r)
函数运行后,在[起始位置,结束位置]
的区间内,位置i
的元素将修改为该区间的内的第i-r+1
小的元素。
并且数组其他位置也发生了改变,[l, i)
的元素将小于等于位置i
的元素,(i, r]
的元素将大于等于位置i
的元素。
最常见的写法:
vector:
nth_element(a.begin(), a.begin() + k, a.end()); // 位置k更新为整个数组第k+1小的数
auto idx = a.begin() + k; // 要访问该数,只能通过迭代器
cout << *idx;
数组:
nth_element(a, a + k, a + n - 1);
cout << a[k];
例子1:
查看中位数:
int n = nums.size();
auto midptr = nums.begin() + n / 2;
nth_element(nums.begin(), midptr, nums.end());
int mid = *midptr;
还可自定义排序方式
例子2:
#include <iostream>
#include <string.h>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
bool mycomp1(int i, int j) {
return (i > j);
}
//以函数对象的方式自定义排序规则
class mycomp2 {
public:
bool operator() (int i, int j) {
return (i > j);
}
};
int main() {
vector<int> myvector{3,1,2,5,4};
//默认的升序排序作为排序规则
auto a = myvector.begin() + 2;
nth_element(myvector.begin(), myvector.begin()+2, myvector.end());
cout << *a << endl;
cout << "第一次nth_element排序:\n";
for (vector<int>::iterator it = myvector.begin(); it != myvector.end(); ++it) {
cout << *it << ' ';
}
cout << endl;
//自定义的 mycomp2() 或者 mycomp1 降序排序作为排序规则
auto b = myvector.begin() + 3;
nth_element(myvector.begin(), myvector.begin() + 3, myvector.end(),mycomp1);
cout << endl << *b << endl;
cout << "第二次nth_element排序:\n";
for (vector<int>::iterator it = myvector.begin(); it != myvector.end(); ++it) {
cout << *it << ' ';
}
return 0;
}
效果: