STL常用算法练习
#include <iostream>
#include <algorithm>
#include <functional>
#include <vector>
#include <list>
#include <iomanip>
#include <iterator> //包含ostream_iterator
using namespace std;
template <typename T> //定义类模板
class ShowElemt
{
public:
ShowElemt()
{
n = 0;
}
void operator()(T &t) //定义函数对象
{
n++; //保持调用状态信息
cout << t << " ";
//printN();
}
void printN()
{
cout << "n: " << n << endl;
}
private:
int n;
};
void showElemt(int &t) //定义普通函数
{
cout << t << " ";
}
//遍历函数
void printV(vector<int> &v)
{
for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
{
cout << setw(8) << setiosflags(ios::right) << *it << " ";
}
cout << endl;
}
//for_each算法 函数对象 回调函数入口地址
//此例子和 Demo0430算法中的函数对象和谓词 中的几乎相似
void test21()
{
vector<int> v1;
v1.push_back(1);
v1.push_back(3);
v1.push_back(5);
printV(v1);
for_each(v1.begin(), v1.end(), showElemt); //通过回调函数
cout << endl;
for_each(v1.begin(), v1.end(), ShowElemt<int>()); //通过函数对象 匿名函数对象
cout << endl;
//匿名函数对象的去和留问题
ShowElemt<int> s1= for_each(v1.begin(), v1.end(), ShowElemt<int>());//初始化
s1.printN();
ShowElemt<int> s2;
s2= for_each(v1.begin(), v1.end(), ShowElemt<int>());//赋值
s2.printN();
ShowElemt<int> s3;
for_each(v1.begin(), v1.end(), s3);
s3.printN(); //此时 n=0 ==>函数对象的传递 是 实参值赋给形参 是元素值传递 不是引用
}
/*------------------------------------------------*/
int increase(int &t)
{
return t + 100;
}
//遍历函数 mylist
void printL(list<int> &v)
{
for (list<int>::iterator it = v.begin(); it != v.end(); it++)
{
cout << setw(8) << setiosflags(ios::right) << *it << " ";
}
cout << endl;
}
//transform算法
void test22()
{
vector<int> v1;
v1.push_back(1);
v1.push_back(3);
v1.push_back(5);
printV(v1);
transform(v1.begin(), v1.end(), v1.begin(), increase);//通过回调函数
printV(v1);
transform(v1.begin(), v1.end(), v1.begin(), negate<int>());//通过函数对象 取负数
printV(v1);
//通过函数对象 和 函数适配器
list<int> mylist;
mylist.resize(v1.size());
//vector中的值乘以10放入mylist中
transform(v1.begin(), v1.end(), mylist.begin(), bind2nd(multiplies<int>(), 10));
printL(mylist);
//结果 直接输出 注意用法
transform(v1.begin(), v1.end(), ostream_iterator<int>(cout, " "), negate<int>());
cout << endl;
}
//for_each算法 和transform算法的异同
int showElemt2(int t) //定义普通函数
{
cout << t << " ";
return t;
}
void test23()
{
vector<int> v1;
v1.push_back(1);
v1.push_back(3);
v1.push_back(5);
printV(v1);
for_each(v1.begin(), v1.end(), showElemt); //通过回调函数
cout << endl;
//“=”: 无法从“void”转换为“int”
//transform(v1.begin(), v1.end(), v1.begin(), showElemt);
//transform中回调函数需要有返回值
transform(v1.begin(), v1.end(), v1.begin(), showElemt2);
cout << endl;
}
int main()
{
//test21();
//test22();
test23();
system("pause");
return 0;
}
预定义函数对象和函数适配器
#include <iostream>
#include <algorithm>
#include <functional>
#include <vector>
#include <string>
using namespace std;
//预定义函数对象和函数适配器
void test11()
{
plus<int> intAdd;
int x = 10;
int y = 15;
int z = intAdd(x, y);
cout << "z: " << z << endl;
plus<string> strAdd;
string s1("aaa");
string s2("bbb");
string s3 = strAdd(s1, s2);
cout << "s3: " << s3 << endl;
vector<string> v1;
v1.push_back("bbb");
v1.push_back("aaa");
v1.push_back("ccc");
v1.push_back("zzzz");
v1.push_back("ccc");
v1.push_back("ccc");
sort(v1.begin(), v1.end(), greater<string>()); //预定义函数对象 降序
for (vector<string>::iterator it = v1.begin(); it != v1.end(); it++)
{
cout << *it << " ";
}
cout << endl;
//计算出现次数
//equal_to有两个参数 _Left参数来自容器 _Right参数来自要计算次数的字符串
//但count_if函数只有3个参数
//要用到函数适配器 :把预定义的函数对象 和 第二个参数进行绑定
int num = count_if(v1.begin(), v1.end(), bind2nd(equal_to<string>(), "ccc"));
cout << "num: " << num << endl;
}
//函数适配器综合案例
class IsGreat
{
public:
IsGreat(int i)
{
m_num = i;
}
bool operator()(int &num) //一元谓词定义
{
if (num > m_num) //m_num是固定值2
{
return true;
}
return false;
}
private:
int m_num;
};
void test12()
{
vector<int> v1;
for (int i = 0; i < 9; i++)
{
v1.push_back(i+1);
}
for (vector<int>::iterator it = v1.begin(); it != v1.end(); it++)
{
cout << *it << " ";
}
cout << endl;
int num1 = count(v1.begin(), v1.end(), 3);
cout << "num1: " << num1 << endl;
//通过 谓词 求大于2的个数
int num2 = count_if(v1.begin(), v1.end(), IsGreat(2));
cout << "num2: " << num2 << endl;
//通过 预定义函数对象 求大于2的个数
//greaterd的第一个参数来自容器 第二个参数为固定值2
int num3 = count_if(v1.begin(), v1.end(), bind2nd(greater<int>(), 2));
cout << "num3: " << num3 << endl;
//求奇数个数 modulus<int>()返回int类型,即刚好整除会返回0
int num4= count_if(v1.begin(), v1.end(), bind2nd(modulus<int>(), 2));//对2取余 不能整除2
cout << "num4: " << num4 << endl;
//求偶数个数 即第三个参数取反,剩下能整除2的值 not1
int num5 = count_if(v1.begin(), v1.end(), not1(bind2nd(modulus<int>(), 2)));
cout << "num5: " << num5 << endl;
}
int main11()
{
//test11();
test12();
system("pause");
return 0;
}