//第二十三模板 18.4算法类 /* STL(标准模板库)通用算法共分四大类 不变序列算法 不对其所作用的容器进行修改 改变序列算法 对其所作用的容器进行修改 排序算法 对容器中的元素采用多种方式进行排序 数值算法 对容器中的元素进行数值计算 这些算法全部在标准命名空间std中的<algorithm>中定义 */ //1 函数对像 //要理解这些标准算法是如何工作的,我们必须了解函数对象的,函数对像即定义的重载运算符() /*#include <iostream> using namespace std; template<class T> class show { public: void operator()(const T&t){ cout<<t<<" "; } }; int main() { show<int>one; for(int i=0; i<10; i++){ one(i); } return 0; }*/ //2 不变序列算法 //不变序列算法即不改变序列中元素的算法 //(1)for_each()方法 /*#include <iostream> #include <vector> #include <algorithm> using namespace std; template<class T> class show { public: void operator()(const T&t) { cout<<t<<" "; } }; int main() { show<int>one; vector<int>vone(10); for(int i=0; i<10; ++i) { vone[i] = i*5; } for_each(vone.begin(),vone.end(),one); //第三个参数是接受一个函数对像,该函数对像执行对所遍历元素的操作,此时one对像可看作为一个函数对像,因此这将调用one函数对像并将遍历到的元素依次传递给one.operator(),这使得到每个元素值次被输出在以屏幕上 system("pause"); return 0; }*/ //(2)find()方法 /*#include <iostream> #include <string> #include <vector> #include <list> #include <algorithm> using namespace std; int main() { list<string> str; list<string>::iterator it; str.push_back("学生"); str.push_back("教师"); str.push_back("校长"); it = find(str.begin(),str.end(),"校长"); if(it == str.end()){ cout<<"没有找到'校长'"<<endl; }else{ cout<<*it<<endl; } system("pause"); return 0; } */ //(3) find_if()方法 //这是一个更强大的find()版本,该方法接收一个函数对像的参数作为参数,并使用它来做更复杂的检测,比如说检测给出的查找条件上是否与某个元素关键字或者关联值相等 /*#include <iostream> #include <string> #include <map> #include <algorithm> using namespace std; typedef map<string,string>::const_iterator CIT; typedef map<string,string>::value_type VT; class func { public: bool operator()(VT&vt) { return vt.second=="1858"; } }; int main() { map<string,string>one; one.insert(VT("创办许汇银行","1897")); one.insert(VT("创办杨大鹏商行","1858")); one.insert(VT("创办二商","1869")); CIT cit = find_if(one.begin(),one.end(),func()); if(cit == one.end()){ cout<<"没有找到"<<endl; }else{ cout<<cit->second<<"\t"<<cit->first<<endl; } return 0; }*/ //(4)adjacent_find() 方法 //该方法返回指向容器中第一组相等元素的迭代器 /*#include <iostream> #include <algorithm> #include <set> using namespace std; typedef multiset<int>::iterator CIT; int main() { multiset<int>one; one.insert(3); one.insert(2); one.insert(9); one.insert(9); one.insert(10); one.insert(10); cout<<"one容器中的元素如下:"<<endl; for(CIT cit=one.begin(); cit!=one.end(); ++cit) { cout<<*cit<<endl; } cout<<endl; cout<<"现在查找并输出第一组相同元素:"<<endl; CIT cit = adjacent_find(one.begin(),one.end()); cout<<*cit<<endl; cit++; cout<<*cit<<endl; cout<<"现在查找并输出第二组相同元素:"<<endl; adjacent_find(cit,one.end()); cit++; cout<<*cit<<endl; cit++; cout<<*cit<<endl; return 0; }*/ //(5)count()方法 该函数返回容器中与给定值相同的元素的个数 //count(first, last, val) /*#include <iostream> #include <algorithm> #include <set> using namespace std; typedef multiset<int>::iterator CIT; int main() { multiset<int>one; one.insert(3); one.insert(2); one.insert(9); one.insert(9); one.insert(10); one.insert(10); cout<<"one容器中的元素如下:"<<endl; for(CIT cit=one.begin(); cit!=one.end(); ++cit) { cout<<*cit<<endl; } int n = count(one.begin(), one.end(), 10); cout<<"在容器中共有"<<n<<"个10"<<endl; return 0; }*/ //equal(first, last, first2); //find(first, last, val) //find_end(first,last,first2,last2) //find_first(first,last,first2,last2) //find_if(first,last,func) //adjacent_find(first,last) //search(first,last,first2,last2) //for_each(first,last,func) //seach(first,last,first2,last2) //3改变序列算法 //copy(first,last,first2) //copy_backward(first,last,first2) //fill(first,last,val) //generate(first,last,func) //partition(first,last,pred) //random_shuffle(first,last) //remove(first,last,val) //replace(first,last,val1,val2) //rotate(first,moddle,last) //reverse(first,last) //swap(iterator1,iterator2) //swap_ranges(first,last,first2) //transform(first,last,first2,func) //unique(first,last) //(1) fill()方法 fill(first,last,val) //该方法把数值val赋值到first到last之间的所有元素 /*#include <iostream> #include <algorithm> #include <vector> using namespace std; template<class T> class show { public: void operator()(const T&t) { cout<<t<<" "; } }; int main() { show<int>one; vector<int>vone(10); fill(vone.begin(),vone.begin()+5,0); //将前五个数设置为0 fill(vone.begin()+5,vone.end(),1); //将后五个数设置为1 for_each(vone.begin(),vone.end(),one); cout<<endl; return 0; }*/ //(2)random_shuffle()方法 //random_shuffle(first,last) 在first到last范围内随机排列元素 /*#include <iostream> #include <vector> #include <algorithm> using namespace std; void show(int val) { cout<<val<<endl; } int main() { vector<int>vint; for(int i=0; i<10;i++){ vint.push_back(i); } for_each(vint.begin(),vint.end(),show); cout<<"乱序输出"<<endl; random_shuffle(vint.begin(),vint.end()); for_each(vint.begin(),vint.end(),show); return 0; }*/ //(3) partition()方法 //partition(first, last, pred) //将一个序列分成两个部分,其中第一个部分包括被函数对像pred作用后返回真值的元素,第二个部分包括被函数对像pred作用后返回假值的元素 /*#include <iostream> #include <vector> #include <algorithm> using namespace std; void show(int val) { cout<<val<<endl; } bool equal(int val){ return (val==5); } int main() { vector<int>one; one.push_back(1); one.push_back(3); one.push_back(4); one.push_back(5); one.push_back(6); one.push_back(4); one.push_back(5); for_each(one.begin(),one.end(),show); cout<<"partition"<<endl; partition(one.begin(),one.end(),equal); for_each(one.begin(),one.end(),show); return 0; }*/ //(4)rotate()方法 //rotate(first,middle,last) //把middle到last范围的元素向左旋转到由first开始的范围中去 /*#include <iostream> #include <vector> #include <algorithm> using namespace std; void show(char val) { cout<<val; } int main() { vector<char>one; one.push_back('h'); one.push_back('e'); one.push_back('l'); one.push_back('l'); one.push_back('o'); one.push_back('w'); one.push_back('o'); one.push_back('r'); one.push_back('l'); one.push_back('d'); for_each(one.begin(),one.end(),show); cout<<endl<<"nrotate"<<endl; rotate(one.begin(),one.begin()+5,one.end()); for_each(one.begin(),one.end(),show); return 0; }*/ //4 排序算法 排序算法即对容器中的元素进行排序操作的算法 //(1)sort()方法 sor(first,last) /*#include <iostream> #include <vector> #include <algorithm> using namespace std; void show(char&r) { cout<<r<<" "; } int main() { vector<char>one; one.push_back('h'); one.push_back('e'); one.push_back('l'); one.push_back('l'); one.push_back('o'); one.push_back('w'); one.push_back('o'); one.push_back('r'); one.push_back('l'); one.push_back('d'); for_each(one.begin(),one.end(),show); cout<<endl<<"sort"<<endl; sort(one.begin(),one.end()); for_each(one.begin(),one.end(),show); return 0; }*/ //(2)sort()方法用一些容器 //STL中标准容器主要有vector,list,deque,string,set,multiset,map和multimay //(3) list类的sort()成员函数与算法类的sort()方法的区别 //(4) partial_sort()方法 //arttial_srot(first,middle,last) //将first到last之间的元素进行排序,并将排好序的元素放到first到middle之间其他放到middle与last之间 /*#include <iostream> #include <vector> #include <algorithm> using namespace std; void show(char&r) { cout<<r<<" "; } int main() { vector<char>one; one.push_back('z'); one.push_back('c'); one.push_back('b'); one.push_back('o'); one.push_back('p'); one.push_back('t'); one.push_back('i'); one.push_back('w'); one.push_back('x'); one.push_back('b'); for_each(one.begin(),one.end(),show); partial_sort(one.begin(),one.begin()+5,one.end()); cout<<endl<<"partial_sort"<<endl; for_each(one.begin(),one.end(),show); return 0; } */ /*#include <iostream> #include <algorithm> #include <functional> #include <vector> #include <string> using namespace std; class student { public: student(const string &a, int b):name(a),score(b){} string name; int score; bool operator<(const student &m)const { return score<m.score; } }; int main() { vector< student> one; student str("王明",74); one.push_back(str); str.name="张胜"; str.score = 100; one.push_back(str); str.name = "徐容花"; str.score=82; one.push_back(str); str.name = "夏宛如"; str.score = 85; one.push_back(str); str.name = "方胜山"; str.score = 48; one.push_back(str); str.name = "常曀"; str.score = 99; one.push_back(str); str.name = "钱话大"; str.score = 77; one.push_back(str); str.name = "杨耳军"; str.score = 24; one.push_back(str); cout<<"-----------调用partial_srot函数前----------"<<endl; for(int i=0; i<one.size(); i++){ cout<<one[i].name<<": \t"<<one[i].score<<endl; } partial_sort(one.begin(),one.begin()+5,one.end()); cout<<"-----------调用partial_srot函数后----------"<<endl; for(int i=0; i<one.size(); i++){ cout<<one[i].name<<": \t"<<one[i].score<<endl; } }*/ //(5) nth_element()方法 //nth_element(first,n,end) //将first到e范nd围内的序列重新排序,使所有小于第n个元素的元素都出现在它前面,而大于它的都出现在后面,重截图使用了自定义的比较函数 /*#include <iostream> #include <algorithm> #include <functional> #include <vector> #include <string> using namespace std; class student { public: student(const string &a, int b):name(a),score(b){} string name; int score; bool operator<(const student &m)const { return score<m.score; } }; int main() { vector< student> one; student str("王明",74); one.push_back(str); str.name="张胜"; str.score = 100; one.push_back(str); str.name = "徐容花"; str.score=82; one.push_back(str); str.name = "夏宛如"; str.score = 22; one.push_back(str); str.name = "方胜山"; str.score = 48; one.push_back(str); str.name = "常曀"; str.score = 99; one.push_back(str); str.name = "钱话大"; str.score = 77; one.push_back(str); str.name = "杨耳军"; str.score = 24; one.push_back(str); cout<<"-----------调用nth_element函数前----------"<<endl; for(int i=0; i<one.size(); i++){ cout<<one[i].name<<": \t"<<one[i].score<<endl; } nth_element(one.begin(),one.begin()+5,one.end()); cout<<"-----------调用nth_element函数后----------"<<endl; for(int i=0; i<one.size(); i++){ cout<<one[i].name<<": \t"<<one[i].score<<endl; } }*/ //该算法设置了一个优化,当区间元素个数不大于32时,直接做一次全排序,只有元素个数超过32时,才采用局部排序算法,即常规的线性复杂的算法 //(6) partition和stable_partition方法 //partition(first,last,pred) //stable_partition方法与partition的使用相同,不过这两个函数凞不是用来排序,它们是用来分类的,比如说,partition可把一个区间中的元素按照某个条件分成两类,它的使用方法我们前面已经介绍过了 /*#include <iostream> #include <algorithm> #include <functional> #include <vector> #include <string> using namespace std; class student { public: //先构造一个 student(const string &a, int b):name(a),score(b){} int score; string name; //重载运算符<,也就是所说的函数对象是吧?汗,现在又不确定这个名词咱说了 //晕错了 //两个const bool operator < (const student &s)const { //如果初始化的值,小于s的值返回真,否则返回假 return score < s.score; } }; int main() { vector<student> one; //定义一个列表,放的是student类型 student str("王明",74); //这里的初始化str的值 one.push_back(str); //下面就不能用初始化值了 str.name="张胜"; str.score = 100; one.push_back(str); str.name = "徐容花"; str.score=82; one.push_back(str); str.name = "夏宛如"; str.score = 22; one.push_back(str); str.name = "方胜山"; str.score = 48; one.push_back(str); str.name = "常曀"; str.score = 99; one.push_back(str); str.name = "钱话大"; str.score = 77; one.push_back(str); str.name = "杨耳军"; str.score = 33; one.push_back(str); cout<<"---------调用nth_element函数前------------"<<endl; for(int i=0; i<one.size(); i++) { cout<<one[i].name<<"\t"<<one[i].score<<endl; } student two("pass",60); //定义对个student,设置分数为60 //partition(one.begin(), one.begin()+5, bind2nd(less<student>(),two) ); //靠,第三个参数麻意思 //没有达到效果啊!!!!!!!! partition(one.begin(), one.end(), bind2nd(less<student>(),two) ); //操,就这么没弄好,开始和结束弄错了,笨蛋一个 cout<<"---------调用nth_element函数后------------"<<endl; for(int i=0; i<one.size(); i++) { cout<<one[i].name<<"\t"<<one[i].score<<endl; } return 0; } //bind2nd(less<student>(),two) //bind2nd()比较函数来实现类似于a<b这样的操作,因为该函数的比较的是,调用bind2nd()函数的对像是否小于two //该程序中我们为bind2nd提供了less()函数对像,或者叫仿函数,在标准模板库中还提供了其他访函数,以下是仿函数列表 //equal_to 相等 //not_equal_two 不相等 //less 小于 //greater 大于 //less_equal 小于等于 //greater_equal 大于等于 //需要注意怕是,这些函数不是都能适用于你的排序算法,如何选择择,取决于你的应用,另外,不能直接写入仿函数的名字,而是要写其重载的函数 //less<int>(); */ //(7)partition和stable_partition的区别 //(8)merge()方法 //merge(first,last,first2,last2,result) //把first和last规定的序列和fiset2,last2所规定的序列一起进行排序,结果放到result开头的序列中,该函数同样具有另一个版本 /*#include <iostream> #include <algorithm> #include <vector> #include <string> using namespace std; void show(string str) { cout<<str<<endl; } int main() { vector<string>one; vector<string>two; vector<string>three(5); one.push_back("one"); one.push_back("two"); one.push_back("three"); two.push_back("four"); two.push_back("five"); cout<<"输出one容器中的所有元素"<<endl; for_each(one.begin(),one.end(),show); cout<<"输出two容器中的所有元素"<<endl; for_each(one.begin(),one.end(),show); //对one two先进行排序 sort(one.begin(),one.end()); sort(two.begin(),two.end()); merge(one.begin(),one.end(),two.begin(),two.end(),three.begin()); cout<<"输出three容器中的所有元素"<<endl; for_each(three.begin(),three.end(),show); return 0; }*/ //因为set容器可以对数据进行自动排序,所以如果用set容器就不用排序了 /*#include <iostream> #include <algorithm> #include <set> #include <string> using namespace std; void show(string str) { cout<<str<<endl; } int main() { set<string>one; set<string>two; set<string>three; one.insert("one"); //set要用insert函数,他没有push_back one.insert("two"); one.insert("three"); two.insert("four"); two.insert("five"); cout<<"输出one容器中的所有元素"<<endl; for_each(one.begin(),one.end(),show); cout<<"输出two容器中的所有元素"<<endl; for_each(one.begin(),one.end(),show); //对one two先进行排序 //sort(one.begin(),one.end()); //sort(two.begin(),two.end()); //merge的用法也不一样 //merge(one.begin(),one.end(),two.begin(),two.end(),inserter(three,three.begin())); merge(one.begin(),one.end(),two.begin(),two.end(),inserter(three,three.begin())); //还是不行,不知道是不是merge不支持这种型式的重载函数, cout<<"输出three容器中的所有元素"<<endl; for_each(three.begin(),three.end(),show); return 0; }*/ //(9) includes()方法 //includes(first,last,first2,last2) //如果first与last范围内的元素与first2,last2之间的元素相等,返回真,否则返回假 /*#include <iostream> #include <algorithm> #include <set> #include <string> using namespace std; void show(string str) { cout<<str<<endl; } int main() { set<string>one; set<string>two; one.insert("one"); //set要用insert函数,他没有push_back one.insert("two"); two.insert("four"); two.insert("five"); cout<<"输出one容器中的所有元素"<<endl; for_each(one.begin(),one.end(),show); cout<<"输出two容器中的所有元素"<<endl; for_each(one.begin(),one.end(),show); bool isIncludes = includes(one.begin(),one.end(),two.begin(),two.end()); if(isIncludes==true) cout<<"两个容器值相同"<<endl; else cout<<"两个容器值不相同"<<endl; return 0; }*/ //该函数必须保证所有容器都已经排序过后再进行比较,如果用vecotr将先使用srot //binary_search(first,last,val) //equal(first,last,first1) //equal_range(first,last,val) //lexicongraphical_compare(first,last,first1,last1) //lower_bound(first,last,val) //max(val1,val2) //max_element(first,last) //min(val1,val2) //min_element(first,last) //next_permutation(first,last) //partial_sort_copy(first,last,first1,last1) //partial_sum(first,last,result) //prev_permutation(first,last) //pop_heap(first,last) //push_heap(first,last) //sort_heap(first,last) //make_heap(first,last)