目录
知识点1【函数对象】(仿函数)
函数对象:重载operator()函数调用运算符的类 实例化的对象 就叫函数对象。
class MyMax
{
public:
int operator()(int a, int b)
{
return a>b?a:b;
}
};
void test01()
{
//ob函数对象:仿函数
MyMax ob;
cout<<ob(10, 20)<<endl;
cout<<MyMax()(100, 50)<<endl;
}
知识点2【谓词】
返回值类型为bool的普通函数或仿函数 都叫谓词。
如果有一个参数:一元谓词
如果有二个参数:二元谓词
#include<vector>
#include<algorithm>
void printVectorInt(int value)
{
cout<<value<<" ";
}
class PrintVectorInt
{
public:
void operator()(int value)
{
cout<<value<<" ";
}
};
bool greaterThan5(int value)//一元谓词
{
return value>5;
}
class GreaterThan5
{
public:
bool operator()(int value)//一元谓词
{
return value>5;
}
};
bool myGreaterInt(int v1, int v2)//二元谓词
{
return v1>v2;
}
class MyGreaterInt
{
public:
bool operator()(int v1, int v2)//二元谓词
{
return v1>v2;
}
};
void test02()
{
vector<int> v;
v.push_back(1);
v.push_back(3);
v.push_back(5);
v.push_back(7);
v.push_back(9);
//普通函数 作为参数 只需要函数名
for_each(v.begin(), v.end(), printVectorInt);
cout<<endl;
//函数对象 作为参数 需要匿名对象
for_each(v.begin(), v.end(), PrintVectorInt());
cout<<endl;
//第一个大于5的数据
vector<int>::iterator ret;
//ret = find_if(v.begin(), v.end(), greaterThan5);
ret = find_if(v.begin(), v.end(), GreaterThan5());
if(ret != v.end())
{
cout<<"找到的值:"<<*ret<<endl;
}
//sort(v.begin(), v.end(), myGreaterInt);
sort(v.begin(), v.end(), MyGreaterInt());
for_each(v.begin(), v.end(), printVectorInt);
cout<<endl;
}
知识点3【内建函数对象】
void test03()
{
vector<int> v;
v.push_back(1);
v.push_back(3);
v.push_back(5);
v.push_back(7);
v.push_back(9);
//普通函数 作为参数 只需要函数名
for_each(v.begin(), v.end(), printVectorInt);
cout<<endl;
//第一个大于5的数据
vector<int>::iterator ret;
ret = find_if(v.begin(), v.end(), bind2nd(greater_equal<int>(),5) );
if(ret != v.end())
{
cout<<"找到的值:"<<*ret<<endl;
}
sort(v.begin(), v.end(), greater<int>() );
for_each(v.begin(), v.end(), printVectorInt);
cout<<endl;
}
知识点4【适配器】
1、函数对象适配器
class PrintVectorInt:public binary_function<int,int, void>
{
public:
void operator()(int value,int tmp) const
{
cout<<value<<" "<<tmp<<endl;
}
};
void test04()
{
vector<int> v;
v.push_back(1);
v.push_back(3);
v.push_back(5);
v.push_back(7);
v.push_back(9);
for_each(v.begin(), v.end(), bind2nd(PrintVectorInt(), 200));
cout<<endl;
for_each(v.begin(), v.end(), bind1st(PrintVectorInt(), 200));
}
2、取反适配器
一个参数 一元取反 not1
二个参数 二元取反 not2
void test05()
{
vector<int> v;
v.push_back(1);
v.push_back(3);
v.push_back(5);
v.push_back(7);
v.push_back(9);
//lambda表达式
for_each(v.begin(), v.end(), [](int value){cout<<value<<" ";} );
cout<<endl;
//sort(v.begin(), v.end(), greater<int>());
sort(v.begin(), v.end(), not2(less<int>()));
for_each(v.begin(), v.end(), [](int value){cout<<value<<" ";} );
cout<<endl;
vector<int>::iterator ret;
ret = find_if(v.begin(), v.end(), not1(bind2nd(greater<int>(), 5)) );
if(ret != v.end())
{
cout<<"找到的数据为:"<<*ret<<endl;
}
}
int main(int argc, char *argv[])
{
test05();
return 0;
}
3、函数指针适配器
4、成员函数适配器
class Data
{
public:
int value;
public:
Data(int value)
{
this->value = value;
}
void myPrintInt()
{
cout<<value<<" ";
}
};
void test07()
{
vector<Data> v;
v.push_back(Data(1));
v.push_back(Data(3));
v.push_back(Data(5));
v.push_back(Data(7));
v.push_back(Data(9));
for_each(v.begin(), v.end(), mem_fun_ref(&Data::myPrintInt) );
cout<<endl;
}
知识点5【常见遍历算法】
#include <algorithm>
for_each算法
/* 遍历算法 遍历容器元素
@param beg 开始迭代器
@param end 结束迭代器
@param _callback 函数回调或者函数对象
@return 函数对象 */
for_each(iterator beg, iterator end,_callback);
transform 算法
#include <iostream>
#include<vector>
#include<algorithm>
using namespace std;
int myTrans(int value)
{
return value+100;
}
void test01()
{
vector<int> v1;
v1.push_back(1);
v1.push_back(3);
v1.push_back(5);
v1.push_back(7);
v1.push_back(9);
vector<int> v2;
v2.resize(v1.size());
transform(v1.begin(), v1.end(), v2.begin(), myTrans);
for_each(v2.begin(), v2.end(), [](int value){cout<<value<<" ";});
cout<<endl;
}
知识点6【常见查找算法】
1、find 找具体的值
2、find_if 按条件查找
3、adjacent_find查找相邻重复元素
4、binary_search二分查找(源数据必须有序)
5、count统计元素出现的次数
6、count_if 按条件统计元素出现的次数
知识点7【常用排序算法】
1、merge两容器合并
void test02()
{
vector<int> v1;
v1.push_back(1);
v1.push_back(3);
v1.push_back(5);
v1.push_back(7);
vector<int> v2;
v2.push_back(2);
v2.push_back(4);
v2.push_back(6);
v2.push_back(8);
vector<int> v3;
v3.resize(v1.size()+v2.size());
merge(v1.begin(),v1.end(), v2.begin(), v2.end(), v3.begin());
for_each(v3.begin(), v3.end(), [](int val){cout<<val<<" ";});
cout<<endl;
}
2、sort排序
3、random_shuffle 洗牌
#include<time.h>
void test03()
{
// 设置随机数种子
srand(time(NULL));
vector<int> v1;
v1.push_back(1);
v1.push_back(3);
v1.push_back(5);
v1.push_back(7);
for_each(v1.begin(), v1.end(), [](int val){cout<<val<<" ";});
cout<<endl;
//洗牌
random_shuffle(v1.begin(), v1.end());
for_each(v1.begin(), v1.end(), [](int val){cout<<val<<" ";});
cout<<endl;
}
4 、reverse翻转
知识点8【常见 拷贝 和 替换 算法】
1、copy拷贝算法
#include<iterator>
void test04()
{
vector<int> v1;
v1.push_back(1);
v1.push_back(3);
v1.push_back(5);
v1.push_back(7);
vector<int> v2;
v2.resize(v1.size());
copy(v1.begin(), v1.end(), v2.begin());
for_each(v2.begin(), v2.end(), [](int val){cout<<val<<" ";});
cout<<endl;
copy(v1.begin(), v1.end(), ostream_iterator<int>(cout, " ") );
}
2、replace替换
3、replace_if
4、swap
#include<iterator>
void test04()
{
vector<int> v1;
v1.push_back(1);
v1.push_back(3);
v1.push_back(5);
v1.push_back(7);
vector<int> v2;
v2.push_back(2);
v2.push_back(4);
v2.push_back(6);
v2.push_back(8);
v2.push_back(18);
v2.push_back(28);
copy(v1.begin(), v1.end(), ostream_iterator<int>(cout, " ") );
cout<<endl;
copy(v2.begin(), v2.end(), ostream_iterator<int>(cout, " ") );
cout<<endl;
swap(v1,v2);
cout<<"------------------"<<endl;
copy(v1.begin(), v1.end(), ostream_iterator<int>(cout, " ") );
cout<<endl;
copy(v2.begin(), v2.end(), ostream_iterator<int>(cout, " ") );
cout<<endl;
}
知识点9【常用算数生成算法】
1、accumulate求和算法
2、fill添加元素
知识点10【常用集合算法】
1、set_intersection求交集
void test05()
{
vector<int> v1;
v1.push_back(1);
v1.push_back(3);
v1.push_back(5);
v1.push_back(7);
v1.push_back(9);
vector<int> v2;
v2.push_back(5);
v2.push_back(7);
v2.push_back(9);
v2.push_back(11);
v2.push_back(12);
vector<int> v3;
v3.resize( min(v1.size(), v2.size()) );
vector<int>::iterator ret;
ret = set_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(), v3.begin());
for_each(v3.begin(), ret, [](int val){cout<<val<<" ";});
cout<<endl;
}
2、set_union并集
3、set_difference
知识点11【STL综合案例:游戏竞技比赛】
#include <iostream>
#include<string>
#include<vector>
#include <map>
#include<string.h>
#include<algorithm>
#include<time.h>
#include<deque>
using namespace std;
class Player
{
public:
string name;
int score[3];
};
void createPlayer(vector<int> &v, map<int,Player> &m)
{
int i=100;
string seed="ABCDEFGHIJKLMNOPQRSTUVWX";
for(;i<124; i++)
{
Player ob;
memset(&ob, 0, sizeof(ob));
ob.name="选手";
ob.name += seed[i-100];
//将选手编号i 放入vector<int> v
v.push_back(i);
//将编号--选手放入 m
m.insert(make_pair(i, ob));
}
}
void playGame(int index,vector<int> &v, map<int,Player> &m, vector<int> &v2)
{
int count=0;//计数 每6人一组
multimap<int,int,greater<int>> mul_map;
//抽签 打乱v的顺序
random_shuffle(v.begin(), v.end());
//打印参赛的选手编号
vector<int>::iterator vit = v.begin();
cout<<"第"<<index<<"轮参加比赛的选手编号如下:"<<endl;
for(;vit!=v.end();vit++)
{
cout<<*vit<<" ";
}
cout<<endl;
//逐个选手参加 比赛
vector<int>::iterator it=v.begin();
//*it == 选手编号
for( ; it!=v.end(); it++)
{
count++;
//10个评委打分
deque<int> d;
int i=0;
for(i=0;i<10;i++)
{
int score = rand()%41+60;
d.push_back(score);
}
//排序
sort(d.begin(), d.end());
//去掉最高分 最低分
d.pop_back();
d.pop_front();
int avg = (accumulate(d.begin(),d.end(),0)/d.size());
m[*it].score[index-1] = avg;
mul_map.insert(make_pair(avg, *it));
if(count%6 == 0)//刚好6人一组
{
//取出mul_map的前三
multimap<int,int,greater<int>>::iterator mit=mul_map.begin();
int i=0;
for(;i<3; mit++,i++)
{
//*mit ==<成绩,编号>
//将晋级的选手编号 放入v2
v2.push_back((*mit).second);
}
#if 1
//打印当前组成绩名单
cout<<"第"<<index<<"轮--"<<"第"<<count/6<<"组的成绩如下"<<endl;
mit=mul_map.begin();
for(;mit!=mul_map.end(); mit++)
{
cout<<"\t选手编号:"<<(*mit).second<<" 成绩:"<<(*mit).first<<endl;
}
#endif
//打印晋级的名单
cout<<"第"<<index<<"轮--"<<"第"<<count/6<<"组的晋级名单如下:"<<endl;
vector<int>::iterator vit=v2.begin()+3*((count/6) -1);
for(;vit!=v2.end();vit++)
{
cout<<"\t"<<*vit<<endl;
}
mul_map.clear();
}
}
}
int main(int argc, char *argv[])
{
//创建24名选手
vector<int> v;//存放选手的编号
map<int,Player> m;//int编号,Player表示选手信息
createPlayer(v, m);
srand(time(NULL));
vector<int> v2;//存放第一轮晋级的编号
playGame(1, v, m, v2);
vector<int> v3;//存放第二轮晋级的编号
playGame(2, v2, m, v3);
vector<int> v4;//存放第三轮晋级的编号
playGame(3, v3, m, v4);
return 0;
}
运行结果: