C++标准程序库 学习笔记 第九章 STL算法

 算法分类: 非变动性算法,变动性算法,移除性算法,变序性算法,排序算法,已序区间算法,数值算法。


1. for_each 算法,调用函数时传递的是值,而不是指针。要改变值,可以传递引用~~。  transform就直接改变值了~~

/*
author: wzy1222 ;
email: 627440781@qq.com
*/
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
void print(vector<int> &coll)
{
	for(vector<int>::iterator iter=coll.begin();iter!=coll.end();++iter)
	{
		cout<<*iter<<" ";
	}
	cout<<endl;
}
//void add_10(int* elem) error  传的不是指针,直接传值 
void out_10(int elem)
{
	elem+=10000;
	cout<<"this is     "<<elem<<endl;
}

int add_100(int elem)
{
	elem+=200000;
	return elem;
}

// 函数对象  仿函数
template<class T>
class WzyFun{
private:
	T valu;
public:
	WzyFun():valu(100){}
	WzyFun(T temp):valu(temp){}

	void operator()(T& elem)  //每一次都传一个值来
	{
		elem+=valu;
	}
};
int main()
{
	int arr[]={1,2,3,4,5,6,7,8,9};
	vector<int> ivec(arr,arr+9);
	print(ivec);

	for_each(ivec.begin(),ivec.end(),out_10);
	for_each(ivec.begin(),ivec.end(),out_10);


	transform(ivec.begin(),ivec.end(),ivec.begin(),add_100);
	print(ivec);
	transform(ivec.begin(),ivec.end(),ivec.begin(),add_100);
	print(ivec);


	// 仿函数很强大~~
	for_each(ivec.begin(),ivec.end(),WzyFun<int>(1000));
	print(ivec);

	system("PAUSE");
	return 0;
}


2.非变动性算法

非变动性算法总结:(不明处运行下例子)

1>search() , find_end() 是区间与区间的匹配。   类似TMP

2>  find_first_of   两区间同时存在的第一个数值。 类似交集。

3> equal mismatch lexicographical_compare()   是区间与区间 元素按顺序比较。  

4> 其它都是单区间内的操作。


/*
author: wzy1222 ;
email: 627440781@qq.com
*/
// 非变动性算法举例
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

template <class T>
void print(T coll)
{
	cout<<"Printing...:  ";
	for(T::iterator iter=coll.begin();iter!=coll.end();++iter)
		cout<<*iter<<" ";
	cout<<endl;
}
bool isOdd(int elem)  //传的都是值
{
	return elem%2==1;
}
bool isMin(int elem1,int elem2)
{
	if(elem1<elem2)
		return true;
	return false;
}
bool isSubOdd(int elem1,int elem2)
{
	return (elem1-elem2)%2==0;
}
bool isLess9(int elem1,int elem2)
{
	return ( elem1>0 && elem2<=9);
}
bool isAdjacent(int elem1,int elem2)
{
	return (elem1%2==0 && elem2%2==1);
}
bool isEqual(int elem1,int elem2)
{
	return (elem1-elem2)%2==0;
}
int main()
{
	int arr[]={1,2,3,4,5,6,7,8,9};
	vector<int> ivec(arr,arr+9);
	print(ivec);

	// count  count_if
	cout<<"count..."<<endl;
	int num=count(ivec.begin(),ivec.end(),9);
	cout<<"查找数字9  num= "<<num<<endl;

	int num2= count_if(ivec.begin(),ivec.end(),isOdd);
	cout<<"查找函数 isOdd num= "<<num2<<endl;

	int num3 = count_if(ivec.begin(),ivec.end(), bind2nd(modulus<int>(),2));
	cout<<" modulus<int>(),2   num= "<<num3<<endl;

	int num4 = count_if(ivec.begin(),ivec.end(), bind2nd( greater<int>(),3));
	cout<<" greater<int>(),3 num= "<<num4 <<endl;

	//最小值和最大值  min_element  max_element
	cout<<endl<<"min_element max_element"<<endl;
	cout<< "最小值是" << * min_element(ivec.begin(),ivec.end()) <<endl;
	cout<< "最大值是" << * max_element(ivec.begin(),ivec.end()) <<endl;
	cout<< "最小值是" << * min_element(ivec.begin(),ivec.end(),isMin) <<endl;

	// 搜寻元素  find  find_if
	cout<<endl<<"find.. find_if..."<<endl;
	vector<int>::iterator iter_find;
	iter_find = find(ivec.begin(),ivec.end(),100);
	if(iter_find != ivec.end())
	{
		cout<<"成功找到元素 " <<*iter_find<<endl; 
	}
	else
		cout<< "没有找到元素 100"<<endl;
	iter_find = find_if(ivec.begin(),ivec.end(),bind2nd( greater<int>(),5));
	if(iter_find != ivec.end())
	{
		cout<<"成功找到元素>5	" <<*iter_find<<endl; 
	}
	else
		cout<< "没有找到元素>5	"<<endl;

	// 搜寻连续n个匹配值  search_n
	cout<<endl<<"search_n..."<<endl;
	vector<int>::iterator iter_search;
	iter_search = search_n(ivec.begin(),ivec.end(),4,7); //连续找4个7
	if(iter_search == ivec.end())
	{
		cout<<"没有找到连续4个7..."<<endl;
	}
	else
		cout<<"找到了连续4个7   "<<*iter_search<<endl;
			// search_n 第二形式用了二元判断式~~ 悲催呀
	iter_search = search_n(ivec.begin(),ivec.end(),4, 5, greater<int>());
	if(iter_search == ivec.end())
	{
		cout<<"没有找到连续4个大于5的值..."<<endl;
	}
	else
		cout<<"找到了连续4个大于5的值,开始项为   "<<*iter_search<<endl;

	//搜寻第一个匹配区间 search  线性效率m+n ,最差m*n~~
	cout<<endl;
	cout<<"两个区间的匹配  搜寻第一匹配区间 search..."<<endl;
	vector<int> vec_search(arr+5,arr+8);
	vector<int>::iterator iter_serch;
	iter_serch=search(ivec.begin(),ivec.end(),vec_search.begin(),vec_search.end());
	if(iter_serch == ivec.end())
	{
		cout<<"没有找到区间完全匹配"<<endl;
	}
	else
		cout<<"找到完全匹配区间,开始项为 "<<*iter_serch<<endl;
	iter_serch = search(ivec.begin(),ivec.end(),vec_search.begin(),vec_search.end(),isSubOdd);
	if(iter_serch == ivec.end())
	{
		cout<<"没有找到区间完全匹配"<<endl;
	}
	else
		cout<<"找到完全匹配区间,开始项为 "<<*iter_serch<<endl;

	//搜寻最后一个匹配区间  find_end      (历史原因,没有命名search_end.. 线性效率m+n ,最差m*n)
	// 同search()
	cout<<endl<<"两个区间的匹配  搜寻最后一个匹配区间... find_end().."<<endl;
	vector<int> vec_findend(arr+3,arr+6);
	vector<int>::iterator iter_findend;
	iter_findend= find_end(ivec.begin(),ivec.end(),vec_findend.begin(),vec_findend.end());
	if(iter_findend == ivec.end())
	{
		cout<<"没有找到区间完全匹配"<<endl;
	}
	else
		cout<<"找到完全匹配区间,开始项为 "<<*iter_findend<<endl;
	iter_findend= find_end(ivec.begin(),ivec.end(),vec_findend.begin(),vec_findend.end(),isSubOdd);
	if(iter_findend == ivec.end())
	{
		cout<<"没有找到区间完全匹配"<<endl;
	}
	else
		cout<<"找到完全匹配区间,开始项为 "<<*iter_findend<<endl;

	// 两个区间中 搜寻元素第一个共同出现的元素  find_first_of     (要找最后一个的话,用反向迭代器)
	cout<<endl<<"两个区间中搜寻同一个元素 find_first_of... "<<endl;
	int arr2[]={9,10};
	vector<int> vec_findfirst(arr2,arr2+2);
	vector<int>::iterator iter_findfirst;
	iter_findfirst = find_first_of(ivec.begin(),ivec.end(),vec_findfirst.begin(),vec_findfirst.end());
	if(iter_findfirst == ivec.end())
	{
		cout<<"没有找到共同的元素"<<endl;
	}
	else
	{
		cout<<"找到第一个共同出现的元素 "<<*iter_findfirst<<endl;
	}
	iter_findfirst = find_first_of(ivec.begin(),ivec.end(),vec_findfirst.begin(),vec_findfirst.end(),isLess9);
	if(iter_findfirst == ivec.end())
	{
		cout<<"没有找到共同的元素"<<endl;
	}
	else
	{
		cout<<"找到第一个共同出现的元素 "<<*iter_findfirst<<endl;
	}

	// 一个区间中 找邻近相等的元素  adjacent_find
	cout<<endl<<"一个区间中找邻近相等的元素 adjacent_find"<<endl;
	vector<int>::iterator iter_adja;
	iter_adja = adjacent_find(ivec.begin(),ivec.end());
	if(iter_adja == ivec.end())
	{
		cout<<"没有相邻相等的哟"<<endl;
	}
	else
	{
		cout<<"找到两个相邻的 "<< *iter_adja<<endl;
	}
	iter_adja = adjacent_find(ivec.begin(),ivec.end(),isAdjacent);
	if(iter_adja == ivec.end())
	{
		cout<<"没有相邻相等的哟"<<endl;
	}
	else
	{
		cout<<"找到两个相邻的 "<< *iter_adja<<endl;
	}

	// 两个区间的比较  判断是否相等 equal  自己要保证第二区间元素的长度要足够
	cout<<endl<<"两个区间的比较,判断是否相等 equal"<<endl;
	int arr3[]={3,4,5,6,7,8,9,10,11};
	vector<int> vec_sec(arr3,arr3+9);
	if( equal(ivec.begin(),ivec.end(),vec_sec.begin()))
	{
		cout<< "equal..."<<endl;
	}
	else
		cout<<" not equal..."<<endl;
	if( equal(ivec.begin(),ivec.end(),vec_sec.begin(),isEqual))
	{
		cout<< "equal..."<<endl;
	}
	else
		cout<<" not equal..."<<endl;

	// 两个区间比较,搜寻第一处不同点  mismatch 返回值是 pair<iter1,iter2>
	cout<<endl<<"两个区间比较 搜寻第一处不同点  mismatch  返回值是pair<iter1,iter2>"<<endl;
	vector<int>::iterator iter_mism;
	iter_mism = mismatch(ivec.begin(),ivec.end(),vec_sec.begin()).first;
	if(iter_mism == ivec.end())
	{
		cout<<"两个区间是相等滴"<<endl;
	}
	else
		cout<<"两个区间第一个不相等的元素是 "<<*iter_mism<<endl;
	iter_mism = mismatch(ivec.begin(),ivec.end(),vec_sec.begin(),isEqual).first;
	if(iter_mism == ivec.end())
	{
		cout<<"两个区间是相等滴"<<endl;
	}
	else
		cout<<"两个区间第一个不相等的元素是 "<<*iter_mism<<endl;
	
	//两个区间比较  是否字典序小于  lexicograpical_compare  区间长度根据最小的长度来~~
	//  第二形式就不举例了,同样传两个参数值~~
	cout<<endl<<"两个区间比较  是否字典序小于  lexicograpical_compare  区间长度根据最小的长度来"<<endl;
	int arr4[]={1,2,3};
	vector<int> vec_cmp(arr4,arr4+3);
	cout<< "区间1字典序小于1,2,3  ?		"<< lexicographical_compare(ivec.begin(),ivec.end(),vec_cmp.begin(),vec_cmp.end())<<endl;
	vector<int> vec_cmp1(arr4+1,arr4+3);
	cout<< "区间1字典序小于 2,3  ?		"<< lexicographical_compare(ivec.begin(),ivec.end(),vec_cmp1.begin(),vec_cmp1.end())<<endl;



	system("PAUSE");
	
	return 0;
}

3. 变动性算法


变动性算法总结:(返回值均为目的区间的下一操作迭代器,即第一个未操作的位置)

1> 单源区间型: fill fill_n generate generate_n( 注意generate不对原值操作,直接赋新值, 仿函数不接参数)  replace replace_if

2> 单源区间+目的区间型: copy  transform(转换功能,仿函数接收一个参数) swap_ranges

3> 两个源区间+目的区间型: transform (结合功能 ,仿函数接收两个参数)..

/*
author: wzy1222 ;
email: 627440781@qq.com ;
*/
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;
template <class T>
void print(T& coll,string str="printing...:")
{
	cout<<str;
	for(T::iterator iter=coll.begin();iter!=coll.end();++iter)
		cout<<*iter<<" ";
	cout<<endl;
}
int main()
{
	int arr[]={1,2,3,4,5,6,7,8,9};
	vector<int> ivec(arr,arr+9);
	vector<int> ivectemp;
	print(ivec,"ivec:");

	// 复制元素 copy copy_backward
	cout<<endl<<"复制元素 copy  copy_backward"<<endl;
	ivectemp = ivec;
	//print(ivec);
	ivectemp.assign(9,0);
	//print(ivectemp);
	copy(ivec.begin(),ivec.end(),ivectemp.begin());
	print(ivectemp,"copy : ");
	
	ivectemp.assign(9,0);
	//print(ivectemp);
	copy_backward(ivec.begin(),ivec.end(),ivectemp.end());
	print(ivectemp,"copy_backward: ");

	//转换元素  transform    结合元素  仍然是transform ..双区间操作 
	cout<<endl<<"转换元素 transform"<<endl;
	transform(ivec.begin(),ivec.end(),ivectemp.begin(),negate<int>());
	print(ivectemp,"transform: ");
	cout<<"结合元素 transform 双区间操作"<<endl;
	transform(ivec.begin(),ivec.end(),ivectemp.begin(),ivectemp.begin(),multiplies<int>());
	print(ivectemp,"transform 双区间乘法:");

	//互换 区间元素内容  swap_ranges
	cout<<endl<<"互换 区间元素内容  swap_ranges"<<endl;
	vector<int> vecswap1,vecswap2;
	vecswap1=ivec;
	vecswap2=ivectemp;
	swap_ranges(vecswap1.begin(),vecswap1.begin()+3,vecswap2.begin());
	print(vecswap1,"vecswap1:");
	print(vecswap2,"vecswap2:");
	
	// 直接赋新值   fill fill_n  直接赋予新产生的数值,调用仿函数不会先传递原先的值~~  generate generate_n
	cout<<endl<<"直接赋新值   fill fill_n generate generate_n"<<endl;
	fill(ivectemp.begin(),ivectemp.end(),3);
	fill_n(ivectemp.begin(),3,100);
	print(ivectemp,"fill+fill_n:");
	// generate 不会传递原先的值,需要参数的仿函数都不能用哟   要实现这功能可以 transform
	generate(ivectemp.begin(),ivectemp.end(),rand);
	print(ivectemp,"generate: ");
	generate_n(ivectemp.begin(),3,rand);
	print(ivectemp,"generate_n: ");

	//替换元素 replace replace_if
	cout<<endl<<"替换元素 replace replace_if"<<endl;
	ivectemp=ivec;
	replace(ivectemp.begin(),ivectemp.end(),5,100);
	print(ivectemp,"replace: ");
	replace_if(ivectemp.begin(),ivectemp.end(),bind2nd(greater<int>(),5),1000);
	print(ivectemp,"replace_if: ");
	// replace_copy型
	ivectemp=ivec;
	replace_copy(ivec.begin(),ivec.end(),ivectemp.begin(),3,100);
	print(ivec,"ivec:");
	print(ivectemp,"ivectemp:");
	replace_copy_if(ivec.begin(),ivec.end(),ivectemp.begin(),bind2nd(greater<int>(),5),5000);
	print(ivec,"ivec:");
	print(ivectemp,"ivectemp:");
	system("PAUSE");
	return 0;
}

4. 移除性算法


移除性算法总结:

一个 remove,一个unique: 注意移除后总大小不变,配合erase才能真正删除。

/*
author: wzy1222 ;
email: 627440781@qq.com ;
*/
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;

template <class T>
void print(T &coll,string str="print...")
{
	cout<<str;
	for(T::iterator iter=coll.begin();iter!=coll.end();++iter)
	{
		cout<<*iter<<" ";
	}
	cout<<endl;
}
int main()
{
	int arr[]={1,2,3,4,5,1,2,3,4};
	vector<int> ivec(arr,arr+9);
	vector<int> ivectemp;
	vector<int>::iterator pos;

	// remove remove_if   把所有符合条件元素移动到覆盖 总数量仍然不变~,返回虚拟末尾~
	cout<<endl<<"remove remove_if..."<<endl;
	ivectemp=ivec;
	pos=remove(ivectemp.begin(),ivectemp.end(),2);
	print(ivectemp,"remove: ");
	ivectemp.erase(pos,ivectemp.end());
	print(ivectemp,"remove+erase: ");

	ivectemp=ivec;
	ivectemp.erase( remove_if(ivectemp.begin(),ivectemp.end(),bind2nd(less<int>(),4)) ,ivectemp.end());
	print(ivectemp,"remove_if+erase: ");

	//  unique 移除重复元素(需要先排序)  当前元素与 前一未被移除的元素 比较
	cout<<endl<<"移除重复元素 unique"<<endl;
	ivectemp=ivec;
	unique(ivectemp.begin(),ivectemp.end());
	print(ivectemp,"没有排序时 unique:");
	ivectemp.erase(unique(ivectemp.begin(),ivectemp.end(),  greater<int>()),ivectemp.end());
	print(ivectemp," op> : ");

	system("PAUSE");
	return 0;
}

5. 变序性算法


变序性算法总结:

reverse 逆转元素次序
rotate 旋转元素次序
next_permutation  pre_permutation    排列元素  !!
random_shuffle  随机洗牌 
partition  stable_partition  元素分割分组!!

/* 
author: wzy1222 ;
email: 627440781@qq.com
*/
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;

template <class T>
void print(T &coll,string str="print...")
{
	cout<<str;
	for(T::iterator iter=coll.begin();iter!=coll.end();++iter)
		cout<<*iter<<" ";
	cout<<endl;
}
int main()
{
	int arr[]={1,2,3,4,5,6,7,8,9};
	vector<int> ivec(arr,arr+9);
	vector<int> ivectemp;
	vector<int>::iterator pos;
	// reverse 逆转元素次序
	cout<<endl<<"reverse 逆转元素次序"<<endl;
	ivectemp=ivec;
	print(ivectemp,"逆序前:");
	reverse(ivectemp.begin(),ivectemp.end());
	print(ivectemp,"逆序后: ");

	// rotate 旋转元素次序
	cout<<endl<<"rotate 旋转元素次序"<<endl;
	ivectemp=ivec;
	print(ivectemp,"旋转前:");
	 //非随机存取迭代器,第二参数可以配合advance使用
	rotate(ivectemp.begin(), ivectemp.begin()+3, ivectemp.end());
	print(ivectemp,"旋转后:");

	// 排列元素  next_permutation  pre_permutation  
	// 如果要遍历所有排列, 必须先排好序,然后一直调用next_permutation至false
	// pre_permutation 降序时用   跟next_permutation相反~~ 不举例了
	cout<<endl<<"排列元素  next_permutation  prev_permutation"<<endl;
	ivectemp.assign(arr,arr+4);
	print(ivectemp,"初始元素:");
	while( next_permutation(ivectemp.begin(),ivectemp.end()) )
	{
		cout<<"  ";
		print(ivectemp," ");
	}

	// 随机洗乱元素  random_shuffle(随机洗牌~)  第三参数先不理了,哥只是弄个随机数~~
	cout<<endl<<"重排元素  random_shuffle(随机洗牌~)"<<endl;
	ivectemp=ivec;
	print(ivectemp,"before shuffle: ");
	random_shuffle(ivectemp.begin(),ivectemp.end());
	print(ivectemp,"random_shuffle: ");
	ivectemp=ivec;
	print(ivectemp,"before shuffle: ");
	random_shuffle(ivectemp.begin(),ivectemp.end());
	print(ivectemp,"random_shuffle: ");

	// 所有元素分割~  partition  stable_partition  快排的partition  就是这个~~
	cout<<endl<<"所有元素分割~  partition  stable_partition  快排的partition  就是这个~~"<<endl;
	ivectemp=ivec;
	print(ivectemp,"before partition: ");
	pos = partition(ivectemp.begin(),ivectemp.end(),bind2nd(modulus<int>(),2));
	print(ivectemp,"partition: ");
	cout<<"the first even number is: "<<*pos<<endl;

	ivectemp=ivec;
	print(ivectemp,"before partition: ");
	pos = stable_partition(ivectemp.begin(),ivectemp.end(),bind2nd(modulus<int>(),2));
	print(ivectemp,"stable_partition: ");
	cout<<"the first even number is: "<<*pos<<endl;


	system("PAUSE");
	return 0;
}

6. 排序算法


排序算法总结:

1> 普通的排序: sort()  sort_heap()。  sort_heap使用前要保证它是一个堆~~

2> 特殊情况排序: 

(1) partition 明确用op分割序列,如: 分割偶数与奇数

(2) partial_sort  局部排序。 如: 只排序前面长度为n的n个元素

(3) nth_element 第n元素排序。 如: 只排序第n个元素。 前面一堆均小于等于且无序,后面一堆大于等于且无序。

/*
author: wzy1222 ;
email: 627440781@qq.com ;
*/
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;
template <class T>
void print(T &coll,string str="print...")
{
	cout<<str;
	for(T::iterator iter=coll.begin();iter!=coll.end();++iter)
		cout<<*iter<<" ";
	cout<<endl;
}
int main()
{
	int arr[]={6,2,7,4,4,0,7,8,1};
	vector<int> ivec(arr,arr+9);
	vector<int> ivectemp;

	// sort stable_sort  stable_sort是稳定排序~
	cout<<endl<<"sort stable_sort  stable_sort是稳定排序~"<<endl;
	ivectemp=ivec;
	print(ivectemp,"排序前:");
	sort(ivectemp.begin(),ivectemp.end());
	print(ivectemp,"排序后:");
	sort(ivectemp.begin(),ivectemp.end(),greater<int>()); //传两个参数值,是值,不是指针~
	print(ivectemp,"greater<int>(): ");


	// partial_sort 局部排序(前面n个都要排好)~  这个好玩
	cout<<endl<<"partial_sort 局部排序(前面n个都要排好)~  这个好玩"<<endl;
	ivectemp=ivec;
	print(ivectemp,"排序前:");
	partial_sort(ivectemp.begin(),ivectemp.begin()+5,ivectemp.end());
	print(ivectemp,"排序后:");

	// nth_element 根据第n个元素 分割   
	// partition() 是以明确op分割(如偶数在前, nth_element 是以所有元素第n大来分割 P404
	cout<<endl<<"nth_element 分割。 只排好第n个元素。  前面跟后面分别<= >=它。但是它们是无序的~  求第n大很好用- -"<<endl;
	ivectemp=ivec;
	int brr[]={3,4,5,6,7,2,3,4,5,6,1,2,3,4,5};
	ivectemp.assign(brr,brr+15);
	print(ivectemp,"排序前:");
	nth_element(ivectemp.begin(),ivectemp.begin()+3,ivectemp.end()); //只有第4小的元素排好,其它被分割。
	print(ivectemp,"第4个已经是有序,注意看其前后:");

	// sort_heap  堆排序(必须保证它是一个堆)~~   需要:make_heap  push_heap pop_heap辅助
	cout<<endl<<"sort_heap  堆排序(必须保证它是一个堆)~~   需要:make_heap  push_heap pop_heap辅助"<<endl;
	ivectemp=ivec;
	print(ivectemp,"初始为: ");
	make_heap(ivectemp.begin(),ivectemp.end());
	print(ivectemp,"make_heap: ");
	pop_heap(ivectemp.begin(),ivectemp.end());
	//只是将其移到最后位置,还要删掉~~
	ivectemp.pop_back();
	print(ivectemp,"pop_heap: ");

	ivectemp.push_back(100);
	//要保证 除了最后一个元素外,前面的是一个堆~
	push_heap(ivectemp.begin(),ivectemp.end());
	print(ivectemp,"push_heap: ");
	sort_heap(ivectemp.begin(),ivectemp.end());
	print(ivectemp,"sort_heap:(必须保证它是一个堆) ");

	system("PAUSE");
	return 0;
}

7. 已序区间算法


已序区间算法总结:(要求已序)

1> binary_search 判断二分查找结果  includes 判断区间包含结果(是否为子集呗)

2>  lower_bound upper_bound equal_range 返回的迭代器,解引用其值,可以有判断大于小于等于其value的效果。

3> 集合运算  merge inplace_merge 合并   set_union 并集set_intersection交集 set_difference 差集1set_symmetricdidderence 差集2

/*
author: wzy1222 ;
email: 627440781@qq.com ;
for: 已序区间算法 ;
*/
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <iterator>
using namespace std;

template <class T>
void print(T &coll,string str="print...: ")
{
	cout<<str<<" ";
	for(T::iterator iter=coll.begin();iter!=coll.end();++iter)
		cout<<*iter<<" ";
	cout<<endl;
}
int main()
{
	int arr[]={1,2,3,4,5,6,7,8,9};
	vector<int> ivec(arr,arr+9);
	vector<int> ivectemp;
	vector<int>::iterator pos1,pos2;
	// binary_search 二分查找(判断是否存在,要得到位置得用lower_bound等函数)
	cout<<endl<<"binary_search 二分查找 判断是否存在"<<endl;
	ivectemp=ivec;
	if( binary_search(ivectemp.begin(),ivectemp.end(),3) )
		cout<<"二分查找找到3"<<endl;
	else
		cout<<"二分查找找不到3"<<endl;

	// inlcudes  判断若干值是否存在  (两个区间都必须排好序~)
	cout<<endl<<"inlcudes  判断若干值是否存在  (两个区间都必须排好序~)"<<endl;
	vector<int> serch;
	serch.push_back(3);
	serch.push_back(4);
	serch.push_back(7);
	ivectemp=ivec;
	print(ivectemp,"ivectemp: ");
	print(serch,"search ");
	if( includes(ivectemp.begin(),ivectemp.end(),serch.begin(),serch.end()))
		cout<<"2区间 是 1区间子集"<<endl;
	else
		cout<<"2区间 不是 1区间子集"<<endl;

	// lower_bound upper_bound equal_ranges 只能找特定值~~
	cout<<endl<<"lower_bound upper_bound equal_ranges 只能找特定值~~"<<endl;
	ivectemp=ivec;
	ivectemp.push_back(5);
	ivectemp.push_back(5);
	ivectemp.push_back(5);
	sort(ivectemp.begin(),ivectemp.end());

	print(ivectemp,"ivectemp");
	pos1= lower_bound(ivectemp.begin(),ivectemp.end(),5);
	pos2= upper_bound(ivectemp.begin(),ivectemp.end(),5);

	cout<<"第一个5在位置 "<<distance(ivectemp.begin(),pos1)+1<<endl;
	cout<<"结束在位置 "<<distance(ivectemp.begin(),pos2)+1<<endl;

	pair<vector<int>::iterator,vector<int>::iterator> pbck;
	pbck=equal_range(ivectemp.begin(),ivectemp.end(),5);
	cout<<"equal_range :"<<*(pbck.first)<<" "<<* (pbck.second)<<endl;

	// merge 合并两个已序区间
	cout<<endl<<"merge 合并两个已序区间"<<endl;
	vector<int> vec1(arr,arr+5);
	vector<int> vec2(arr+3,arr+7);
	vector<int> vec3;
	merge(vec1.begin(),vec1.end(),vec2.begin(),vec2.end(),back_inserter(vec3));
	print(vec1,"vec1:");
	print(vec2,"vec2:");
	print(vec3,"vec3:");

	// set_union 已序集合的并集
	cout<<endl<<"set_union 已序集合的并集"<<endl;
	vec3.clear();
	set_union(vec1.begin(),vec1.end(),vec2.begin(),vec2.end(),back_inserter(vec3));
	print(vec1,"vec1:");
	print(vec2,"vec2:");
	print(vec3,"vec3:");

	// set_intersection 已序集合的交集
	cout<<endl<<"set_intersection 已序集合的交集"<<endl;
	vec3.clear();
	set_intersection(vec1.begin(),vec1.end(),vec2.begin(),vec2.end(),back_inserter(vec3));
	print(vec1,"vec1:");
	print(vec2,"vec2:");
	print(vec3,"vec3:");

	// set_difference 已序集合的差集  存在于第一区间 不存在于第二区间
	cout<<endl<<"set_difference 已序集合的差集 不存在于第二区间"<<endl;
	vec3.clear();
	set_difference(vec1.begin(),vec1.end(),vec2.begin(),vec2.end(),back_inserter(vec3));
	print(vec1,"vec1:");
	print(vec2,"vec2:");
	print(vec3,"vec3:");

	// set_symmetric_difference 已序集合的差集  或在第一,或在第二,不同时存在
	cout<<endl<<"set_symmetric_difference 已序集合的差集  或在第一,或在第二,不同时存在"<<endl;
	vec3.clear();
	set_symmetric_difference(vec1.begin(),vec1.end(),vec2.begin(),vec2.end(),back_inserter(vec3));
	print(vec1,"vec1:");
	print(vec2,"vec2:");
	print(vec3,"vec3:");

	// inplace_merge 原地合并 原区间拆为两部分,要求两部分都已序
	cout<<endl<<"inplace_merge 原地合并 原区间拆为两部分,要求两部分都已序"<<endl;
	vec3.clear();
	vec3.push_back(4);
	vec3.push_back(5);
	vec3.push_back(6);
	vec3.push_back(7);
	vec3.push_back(1);
	vec3.push_back(2);
	vec3.push_back(3);
	vec3.push_back(4);
	pos1=vec3.begin()+4;
	print(vec3,"vec3:");
	inplace_merge(vec3.begin(),pos1,vec3.end());
	print(vec3,"vec3:");

	system("PAUSE");
	return 0;
}

8. 数值算法


数值算法总结:

1> accumulate 序列求和value+a1+a2+a3+...   op为+

2> inner_product    两序列内积  value+a1*b1+a2*b2+..   op1为+  op2为*.

3> adjacent_difference  相邻两项差  a1,a2-a1,a3-a2..    op为-

4> partial_sum  前n项和  a1,a1+a2,a1+a2+a3..  op为+

/*
author: wzy1222 ;
email: 627440781@qq.com
for: 数值算法
*/
#include <iostream>
#include <vector>
#include <string>
#include <numeric>
using namespace std;
template <class T>
void print(T &coll,string str="print...:")
{
	cout<<str<<" ";
	for(T::iterator iter=coll.begin();iter!=coll.end();++iter)
		cout<<*iter<<" ";
	cout<<endl;
}
int main()
{
	int arr[]={1,2,3,4,5,6,7,8,9,10};
	vector<int> ivec1(arr,arr+5);
	vector<int> ivec2(arr+5,arr+10);

	// accumulate  加法 return value+a1+a2+a3+...  +为op
	cout<<endl<<"accumulate  加法  return value+a1+a2+a3+...  +为op:"<<endl;
	cout<< accumulate(ivec1.begin(),ivec1.end(),100) <<endl;
	cout<< accumulate(ivec1.begin(),ivec1.end(),2,multiplies<int>())<<endl;

	// inner_product 内积 return value+a1*b1+a2*b2+...  +为op1 *为op2
	cout<<endl<<"inner_product 内积 return value+a1*b1+a2*b2+...  +为op1 *为op2"<<endl;
	cout<< inner_product(ivec1.begin(),ivec1.end(),ivec2.begin(),10000)<<endl;
	cout<< inner_product(ivec1.begin(),ivec1.end(),ivec2.begin(),10000,plus<int>(),plus<int>())<<endl;

	// partial_sum 前n项和 a1,a1+a2,a1+a2+a3..  +为op
	cout<<endl<<"partial_sum 前n项和 a1,a1+a2,a1+a2+a3..  +为op"<<endl;
	print(ivec1,"source:");
	partial_sum(ivec1.begin(),ivec1.end(),ivec2.begin());
	print(ivec2,"dest:");
	partial_sum(ivec1.begin(),ivec1.end(),ivec2.begin(),multiplies<int>());
	print(ivec2,"op 为 * :");

	// adjacent_difference 相邻两位相减 a1,a2-a1,a3-a2... -为op  (数列的求通项~~)
	// adjacent_difference 和 partial_sum 互补的~~ 高中数列知识,不解释
	cout<<endl<<"adjacent_difference 相邻两位相减 a1,a2-a1,a3-a2... -为op  (数列的求通项~~)"<<endl;
	print(ivec1,"source:");
	adjacent_difference(ivec1.begin(),ivec1.end(),ivec2.begin());
	print(ivec2,"dest:");
	adjacent_difference(ivec1.begin(),ivec1.end(),ivec2.begin(),plus<int>());
	print(ivec2,"op 为 +:");

	cout<<endl<<" adjacent_difference 和 partial_sum 互补的~~ 高中数列知识,不解释"<<endl;
	system("PAUSE");
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值