STL的基本算法

#include <iostream>
#include<functional>
#include<list>
#include<vector>
#include<set>
#include<iterator>
#include<algorithm>
#include<memory>
using namespace std;

template<class T>
void Print(const T& t,char *str="")
{
	cout << str;
	//获得t模板的类型,如t为vector<int>,则value_type为int
	typedef typename iterator_traits<T::iterator>::value_type value_type;
	for_each(t.begin(), t.end(), [](value_type _t) {cout << _t << " , "; });
	cout << endl;
}
//查找算法
void FindAlgorithm()
{
	int num[] = { 1,2,2,3,3,3,4,4,4,4 };
	vector<int> v;
	v.assign(num, num + 10);
	Print(v);
	auto pos = find(v.begin(), v.end(), 4); //返回第一个找到的iterator,如果找不到则返回end()
	cout << "第一个4的位置" << distance(v.begin(), pos) + 1 << endl;//7

	auto pos2 = find_if(v.begin(), v.end(), bind2nd(greater<int>(), 3));
	cout << "第一个大于3的位置" << distance(v.begin(), pos2) + 1 << endl;//7

	auto pos3 = search_n(v.begin(), v.end(), 3, 3);
	cout << "3个3的位置" << distance(v.begin(), pos3) + 1 << endl;//4

	auto pos4 = search_n(v.begin(), v.end(), 4, 3, greater<int>());
	cout << "4个大于3的位置" << distance(v.begin(), pos4) + 1 << endl;//7

	int subnum[] = { 3,3,4 };
	auto pos5 = search(v.begin(), v.end(), subnum, subnum + 3);
	cout << "子串位置" << distance(v.begin(), pos5) + 1 << endl;

	auto pos6 = search(v.begin(), v.end(), subnum, subnum + 3, [](int a, int b) {return a == b - 1; });
	cout << "子串减一后匹配原串的位置,此处即匹配[2,2,3] " << distance(v.begin(), pos6) + 1 << endl;//2

	auto pos7 = adjacent_find(v.begin(), v.end());
	cout << "第一个有两个连续相等的元素位置" << distance(v.begin(), pos7) + 1 << endl;//2

	auto pos8 = adjacent_find(v.begin(), v.end(), [](int left, int right) {return left * 2 == right; });
	cout << "第一个有两个连续元素左边为右边为两倍的位置" << distance(v.begin(), pos8) + 1 << endl; //1
}
//比较算法
void CompareAlgorithm()
{
	int num[] = { 1,2,3,4,5 };
	int num2[] = { 2,3,4,5,6 };
	vector<int>v1, v2;
	v1.assign(num, num + 5);
	v2.assign(num2, num2 + 5);
	bool b1 = equal(v1.begin(), v1.end(), v2.begin());
	bool b2 = equal(v1.begin(), v1.end(), v2.begin(), [](int left, int right) {return left + 1 == right; });
	cout << b1 << "," << b2 << endl; //输出为0,1

									 //p1返回v1,v2不同元素的迭代器组成的pair,若v1,v2相同,则 p1.first == v1.end()
	auto p1 = mismatch(v1.begin(), v1.end(), v2.begin());
	cout << *p1.first << " , " << *p1.second << endl; //输出1,2
	auto p2 = mismatch(v1.begin(), v1.end(), v2.begin(), [](int left, int right) {return left * 2 == right; });
	cout << *p2.first << " , " << *p2.second << endl;//输出2,3 因为num[0] * 2 == num2[0],而num[1]*2 != num2[1]

	cout << lexicographical_compare(v1.begin(), v1.end(), v2.begin(), v2.end());//默认比较v1是否小于v2
}
//拷贝算法
void CopyAlgorithm()
{
	int num[] = { 1,2,3,4,5 };
	vector<int>v;
	v.assign(num, num + 5);
	list<int>L1;
	/*copy(v.begin(), v.end(), ostream_iterator<int>(cout, ","));
	cout << endl;*/
	copy(v.begin(), v.end(), back_inserter(L1));//使用插入型迭代器,此时L1为1,2,3,4,5
	Print(L1);

	//将 2,3拷贝到v的最后面,此时L1为1,2,3,2,3
	copy_backward(v.begin() + 1, v.begin() + 3, L1.end());
	Print(L1);

	//将v中的偶数拷贝到L1开头,此时L1为2,4,3,2,3
	copy_if(v.begin(), v.end(), L1.begin(), [](int t) {return t % 2 == 0; });
	Print(L1);

	//在拷贝过程中删除一些元素,此例删除3,即将v中的3删掉,剩余元素拷贝到L1开头,此时L1为1,2,4,5,3
	remove_copy(v.begin(), v.end(), L1.begin(), 3);
	Print(L1);

	//在拷贝过程中删除偶数,此时L1为 1,3,5,5,3
	remove_copy_if(v.begin(), v.end(), L1.begin(), [](int t) {return t % 2 == 0; });
	Print(L1);
}
//转换算法,将转换与拷贝集合到一起
void TransformAlgorithm()
{
	int num[] = { 1,2,3,4,5 };
	vector<int>v;
	v.assign(num, num + 5);
	list<int>L;
	//将v中的元素分别乘-1后插入到L中
	transform(v.begin(), v.end(), back_inserter(L), negate<int>());
	Print(L);

	//将v中的元素分别乘10后插入到L的开头
	//plus<int>() ,divides<int>()  ,minus<int>()
	transform(v.begin(), v.end(), L.begin(), bind2nd(multiplies<int>(), 10));
	Print(L);

	//将v*v拷贝到L开头
	transform(v.begin(), v.end(), v.begin(), L.begin(), multiplies<int>());
	Print(L);

	//使用自定义函数

	//template<class T>
	//class customFunc
	//{
	//public:
	//	customFunc(const T & t) :value(t) {}
	//	int operator()(const T &t)const
	//	{
	//		return t * value;
	//	}
	//private:
	//	T value;
	//};
	//template<class T>
	//class customFunc2
	//{
	//public:
	//	customFunc2(const T & t) :value(t) {}
	//	int operator()(const T &t1, const T&t2)const
	//	{
	//		return (t1 + t2)*value;
	//	}
	//private:
	//	T value;
	//};



	将v中的元素分别乘3后插入到L中
	//等价于transform(v.begin(), v.end(), back_inserter(L), [](int t) {return t * 3; });
	//transform(v.begin(), v.end(), back_inserter(L), customFunc<int>(3));
	
	//Print(L);
	将v中的元素分别加上L的元素再乘2,最后拷贝到L的起始位置处
	//transform(v.begin(), v.end(), L.begin(), L.begin(), customFunc2<int>(2));
	//Print(L);
}
//交换算法
void SwapAlgorithm()
{
	int num[] = { 1,2,3,4,5 };
	vector<int>v;
	v.assign(num, num + 5);
	vector<int>L;
	transform(v.begin(), v.end(), back_inserter(L), [](int t) {return t + 10; });
	Print(L);//11,12,13,14,15
	swap_ranges(v.begin(), v.begin() + 3, L.begin());
	Print(v, "v:");//11 12 13 4 5
	Print(L, "L:");//1,2,3,14,15

	//swap(v, L);
}
//赋值算法
void AssignAlgorithm() 
{
	int num[] = { 1,2,3,4,5,6,7,8,9 };
	vector<int>v;
	v.assign(num, num + 9);
	//将v的前4个元素赋值为10
	fill(v.begin(), v.begin() + 4, 10);
	Print(v);
	//从begin位置开始的3个数赋值为20
	fill_n(v.begin(), 3, 20);
	Print(v);

	//generate(v.begin(), v.end(), rand);
	//Print(v);
	//生成4个随机数拷贝到v.begin 开始的4个位置处
	generate_n(v.begin(), 4, rand);
	Print(v);
}
//替换算法
void ReplaceAlgorithm()
{
	int num[] = { 1,2,4,4,5,6,7,8,9 };
	vector<int>v;
	v.assign(num, num + 9);
	//将所有的4换成5
	replace(v.begin(), v.end(), 4, 5);
	Print(v);
	//将所有大于5的数换成0
	replace_if(v.begin(), v.end(), bind2nd(greater<int>(), 5), 0);
	Print(v);
}
//翻转算法
void ReverseAlgorithm()
{
	int num[] = { 1,2,4,4,5,6,7,8,9 };
	vector<int>v;
	list<int>L;
	v.assign(num, num + 9);
	L.assign(num, num + 9);

	auto posL = L.begin();
	auto posR = L.end();
	advance(posL, 2);//list的迭代器不可加减,要使用advance函数来移动
	advance(posR, -2);
	reverse(v.begin() + 2, v.end() - 2);
	reverse(posL, posR);//翻转L的第3-7个元素
	Print(L, "L:");//1,2,,7,6,5,4,3,8,9
	Print(v, "v:");


	vector<int>v2;
	reverse_copy(v.begin(), v.end(), back_inserter(v2));//将v翻转后拷贝到v2中
	Print(v2);
}
//排列算法
void ShuffleAlgorithm()
{
	int num[] = { 1,2,3,4,5,6,7,8,9 };
	vector<int>v;
	list<int>L;
	v.assign(num, num + 9);
	L.assign(num, num + 9);

	random_shuffle(v.begin(), v.begin() + 5);//随机重排,遵循均匀分布。也可跟第三个参数,给出一个仿函数
	Print(v);

	//while (next_permutation(v.begin(), v.end(), [](int a,int b) {return a > b; }));//降序
	Print(v);
}
//排序算法
void SortAlgorithm()
{
	int num[] = { 4,8,5,9,6,2,7,3,1 };
	vector<int>v;
	v.assign(num, num + 9);
	//sort(v.begin(), v.end());//sort和stable_sort需要访问随机访问型迭代器,所以只能对vector和deque有用
	//对于sort里第三个函数的排序问题可参考此题 https://www.nowcoder.com/pat/6/problem/4041
	Print(v);
	partial_sort(v.begin(), v.begin() + 5, v.end());//保证前5个元素是已排列的
	nth_element(v.begin(), v.begin() + 5, v.end());//保证位置5处左边的都比它小,右边的都比他大。但是vs上是全排列?
	Print(v);
}
//合并,交集,差集算法
void MergeAndOther()
{
	int num[] = { 1,2,3,4,5,6,7,8 };
	int num2[] = { 3,4,5,6,7,8,9,10 };
	vector<int>v;
	v.assign(num, num + 8);
	set<int>s;
	for (auto i : num2)
		s.insert(i);

	vector<int>res;
	//将v与s合并到res中,注:要保证v和s是有序的
	auto p = merge(v.begin(), v.end(), s.begin(), s.end(), back_inserter(res));
	Print(res);

	res.clear();
	//两个已排序集合的并集
	set_union(v.begin(), v.end(), s.begin(), s.end(), back_inserter(res));
	Print(res);

	res.clear();
	//两个已排序集合的交集
	set_intersection(v.begin(), v.end(), s.begin(), s.end(), back_inserter(res));
	Print(res);

	res.clear();
	//两个已排序集合的差集,新生元素是含在第一个源区间中的元素
	set_difference(v.begin(), v.end(), s.begin(), s.end(), back_inserter(res));
	Print(res);
}
//删除算法
void DeleteElement()
{
	int num[] = { 1,2,3,3,5,6,7,8 };
	vector<int>v;
	v.assign(num, num + 8);

	//移除重复元素,并返回删除后容器的末尾位置的迭代器,此位置非常重要
	auto p = unique(v.begin(), v.end());
	v.erase(p, v.end());
	Print(v);

	//删除区间内为3的元素,返回值同上
	auto p2 = remove(v.begin(), v.end(), 3);
	v.erase(p2, v.end());//必须要删除掉末尾的几个元素
						 //for_each(v.begin(), p, [](int t) {cout << t << ","; });
	Print(v);

	//删除所有大于3的元素
	auto p3 = remove_if(v.begin(), v.end(), [](int t) {return t > 3; });
	v.erase(p3, v.end());
	Print(v);
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值