常用库函数


#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;
}

效果:

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值