//STL的常用算法
//算法主要是由<algorithm> <functional><numeric>组成
//<algorithm> STL头文件中最大的一个 范围涉及到 比较,交换,查找,遍历,复制,修改等
//<numeric>体积很小 只包括几个在序列上面进行简单教学运算的模板函数
//<functional>定义了一些模板类,用以声明函数对象
1//常用遍历算法
//for_each 遍历容器
//普通函数
void print01(int val)
{
cout << val <<" ";
}
//仿函数
class myprint02
{
public:
void operator()(int val)
{
cout << val << " ";
}
};
void test01()
{
vector<int> v;
for(int i = 0; i <10; i++)
{
v.push_back(i);
}
//普通函数,放一个函数名
for_each(v.begin(),v.end(),print01);
cout << endl;
//仿函数,必须传一个函数对象,所以要传一个匿名的函数对象
for_each(v.begin(),v.end(),myprint02());
cout << endl;
}
int main()
{
//创建随机因子;
srand((unsigned)time(NULL));
test01();
pause();
return 0;
}
2 transform算法
//常用遍历算法
//transform
//注意 目标容器需要提前开辟空间
//仿函数
//写这个仿函数,可以让transform的过程中可以做一些操作
class TransForm
{
public:
int operator()(int val)
{
return val+100;
}
};
class myprint
{
public:
void operator()(int val)
{
cout << val << " ";
}
};
void test01()
{
vector<int> v;
for(int i = 0; i <10; i++)
{
v.push_back(i);
}
vector<int> vtarget;
vtarget.resize(v.size());
transform(v.begin(),v.end(),vtarget.begin(),TransForm());
for_each(vtarget.begin(),vtarget.end(),myprint());
cout << endl;
}
2 常用查找算法
//find //查找元素 返回迭代器
//find_if //按条件查找 返回迭代器
//adjacent_find //查找相邻重复元素
//binary_search //二分查找法
//count //统计元素个数
//count_if //按条件统计
1 find
//STL常用算法
//查找算法
//1.find
// 查找内置数据类型
void test01()
{
vector<int> v;
for(int i = 0; i< 10;i++)
{
v.push_back(i);
}
vector<int>::iterator pos = find(v.begin(),v.end(),5);
if(pos == v.end())
{
cout << "None" << endl;
}
else
{
cout << "find"<<endl;
}
}
//查找自定义数据
//必须重载==号
class person
{
public:
person(string name ,int age)
{
this->m_name = name;
this->m_age = age;
}
bool operator==(const person &p)
{
if( this->m_name == p.m_name
&& this->m_age == p.m_age)
{
return true;
}
else
{
return false;
}
}
string m_name;
int m_age;
};
void test02()
{
vector<person> v;
person p1("aa",10);
person p2("bb",20);
person p3("cc",30);
person p4("dd",40);
v.push_back(p1);
v.push_back(p2);
v.push_back(p3);
v.push_back(p4);
person pp("bb",20);
//需要重载==号
vector<person>::iterator it = find(v.begin(),v.end(),pp);
if(it != v.end())
{
cout << "find " << it->m_age << it->m_name << endl;
}
else
{
cout << "None" << endl;
}
}
2 find_if
//2.find_if
class greaterfive
{
public:
bool operator()(int val)
{
return val > 5;
}
};
//内置数据类型
void test01()
{
vector<int> v;
for(int i = 0 ;i < 10 ; i++)
{
v.push_back(i);
}
vector<int>::iterator pos = find_if(v.begin(),v.end(),greaterfive());
if(pos == v.end())
{
cout << "None" << endl;
}
else
{
cout << "find: "<< *pos << endl;
}
pos++;
cout << *pos << endl;
}
//自定义数据类型
class person
{
public:
person(string name,int age)
{
this->m_name = name;
this->m_age = age;
}
string m_name;
int m_age;
};
class greater20
{
public:
bool operator()(const person &p)
{
return p.m_age > 20;
}
};
void test02()
{
vector<person> v;
person p1("a",10);
person p2("b",20);
person p3("c",30);
person p4("d",40);
v.push_back(p1);
v.push_back(p2);
v.push_back(p3);
v.push_back(p4);
vector<person>::iterator it = find_if(v.begin(),v.end(),greater20());
if(it == v.end())
{
cout << "none"<<endl;
}
else
{
cout << it->m_name << it->m_age<<endl;;
}
}
3 adjacent_find
//查找算法
//3.adjecent_find
//查找重复相邻
//内置数据类型
void test01()
{
vector<int> v;
v.push_back(0);
v.push_back(2);
v.push_back(0);
v.push_back(3);
v.push_back(1);
v.push_back(4);
v.push_back(3);
v.push_back(3);
vector<int>::iterator pos = adjacent_find(v.begin(),v.end());
if(pos == v.end())
{
cout << "None" << endl;
}
else
{
cout << "find: "<< *pos << endl;
}
}
//自定义数据类型
class person
{
public:
person(string name,int age)
{
this->m_name = name;
this->m_age = age;
}
bool operator==(const person &p)
{
if(this->m_name == p.m_name
&& this->m_age == p.m_age)
{
return true;
}
else
{
return false;
}
}
string m_name;
int m_age;
};
void test02()
{
vector<person> v;
person p1("a",10);
person p2("b",20);
person p3("b",20);
person p4("d",40);
v.push_back(p1);
v.push_back(p2);
v.push_back(p3);
v.push_back(p4);
vector<person>::iterator it = adjacent_find(v.begin(),v.end());
if(it == v.end())
{
cout << "none"<<endl;
}
else
{
cout << it->m_name << it->m_age<<endl;;
}
}
4 binary_search
自定义数据是我自己写的,似乎自定义数据无法判断顺序是否有序,所以不适合用binary_search查找
//3.binary_search
//二叉树查找
//内置数据类型
void test01()
{
vector<int> v;
for(int i = 0;i<10;i++)
{
v.push_back(i);
}
//必须查找有序序列
//如果是无序序列,结果未知
bool ret = binary_search(v.begin(),v.end(),9);
if(ret == true)
{
cout << "find" << endl;
}
else
{
cout << "None" << endl;
}
}
//自定义数据类型
class person
{
public:
person(string name,int age)
{
this->m_name = name;
this->m_age = age;
}
string m_name;
int m_age;
};
bool operator<(const person &p1,const person &p2)
{
if(p1.m_name < p2.m_name
&& p1.m_age < p2.m_age)
{
return true;
}
else
{
return false;
}
}
void test02()
{
vector<person> v;
person p1("a",10);
person p2("b",20);
person p3("c",30);
person p4("d",40);
v.push_back(p1);
v.push_back(p2);
v.push_back(p3);
v.push_back(p4);
person pp("c",30);
bool ret = binary_search(v.begin(),v.end(),pp);
if(ret == false)
{
cout << "none"<<endl;
}
else
{
cout << "find"<<endl;;
}
}
5 统计
我有一个疑问:为什么binary_search的 operator< 就要作为全局函数,而operator==就可以全局也可以,类成员也可以?这是为什么?
//STL常用算法
//查找算法
//3.count
//统计
//内置数据类型
void test01()
{
vector<int> v;
for(int i = 0;i<10;i++)
{
v.push_back(2);
}
int num = count(v.begin(),v.end(),2);
{
cout << num << endl;
}
}
//自定义数据类型
class person
{
public:
person(string name,int age)
{
this->m_name = name;
this->m_age = age;
}
bool operator==(const person &p2)
{
if(this->m_name == p2.m_name
&& this->m_age == p2.m_age)
{
return true;
}
else
{
return false;
}
}
string m_name;
int m_age;
};
// bool operator==(const person &p1,const person &p2)
// {
// if(p1.m_name == p2.m_name
// && p1.m_age == p2.m_age)
// {
// return true;
// }
// else
// {
// return false;
// }
// }
void test02()
{
vector<person> v;
person p1("a",10);
person p2("c",30);
person p3("c",30);
person p4("d",40);
v.push_back(p1);
v.push_back(p2);
v.push_back(p3);
v.push_back(p4);
person pp("c",30);
int num = count(v.begin(),v.end(),pp);
cout << num <<endl;
}
6 有条件统计count_if
//查找算法
//3.count_if
//统计
class greater2
{
public:
bool operator()(int val)
{
return val > 2;
}
};
//内置数据类型
void test01()
{
vector<int> v;
for(int i = 0;i<10;i++)
{
v.push_back(i);
}
int num = count_if(v.begin(),v.end(),greater2());
{
cout << num << endl;
}
}
//自定义数据类型
class person
{
public:
person(string name,int age)
{
this->m_name = name;
this->m_age = age;
}
string m_name;
int m_age;
};
class greater10
{
public:
bool operator()(const person &p)
{
return p.m_age > 10;
}
};
void test02()
{
vector<person> v;
person p1("a",10);
person p2("b",20);
person p3("c",30);
person p4("d",40);
v.push_back(p1);
v.push_back(p2);
v.push_back(p3);
v.push_back(p4);
int num = count_if(v.begin(),v.end(),greater10());
cout << num <<endl;
}
3.常用排序算法
1 sort
//STL常用算法
//排序算法
//sort //对容器内元素进行排序
//random_shuffle //洗牌
void myprint(int val)
{
cout << val << " ";
}
//内置数据类型
void test01()
{
vector<int> v;
v.push_back(10);
v.push_back(30);
v.push_back(20);
v.push_back(40);
v.push_back(50);
//利用sort进行排序
//升序
sort(v.begin(),v.end());
for_each(v.begin(),v.end(),myprint);
cout << endl;
//降序
sort(v.begin(),v.end(),greater<int>());
for_each(v.begin(),v.end(),myprint);
cout << endl;
}
2 random_shuffle
//STL常用算法
//排序算法
//sort //对容器内元素进行排序
//random_shuffle //洗牌
void myprint(int val)
{
cout << val << " ";
}
//内置数据类型
void test01()
{
vector<int> v;
for(int i=0;i<10;i++)
{
v.push_back(i);
}
//利用random_shuffle进行洗牌
//为了打乱的更随机,需要添加随机因子
random_shuffle(v.begin(),v.end());
for_each(v.begin(),v.end(),myprint);
cout << endl;
}
3 merge
两个有序容器合并,并存储到另一个容器中,也是有序的,另外源容器的有序需要是同一序列
目标容器需要提前分配空间
void myprint(int val)
{
cout << val << " ";
}
//内置数据类型
void test01()
{
vector<int> v1;
for(int i=0;i<9;i++)
{
v1.push_back(i);
}
vector<int> v2;
for(int i=1;i<10;i++)
{
v2.push_back(i);
}
//vtrage 目标容器需要提前分配空间
vector<int> vtarge;
vtarge.resize(v1.size()+v2.size());
merge(v1.begin(),v1.end(),v2.begin(),v2.end(),vtarge.begin());
for_each(vtarge.begin(),vtarge.end(),myprint);
cout << endl;
}
4 reverse
void myprint(int val)
{
cout << val << " ";
}
//内置数据类型
void test01()
{
vector<int> v1;
for(int i=0;i<9;i++)
{
v1.push_back(i);
}
reverse(v1.begin(),v1.end());
for_each(v1.begin(),v1.end(),myprint);
cout << endl;
}
//自定义数据?
class person
{
public:
person(string name,int age)
{
this->m_name = name;
this->m_age = age;
}
string m_name;
int m_age;
};
void printperson(const person &p)
{
cout << p.m_name << " " << p.m_age << " ";
}
void test02()
{
vector<person> vp;
person p1("a",10);
person p2("b",11);
person p3("c",12);
person p4("d",13);
vp.push_back(p1);
vp.push_back(p2);
vp.push_back(p3);
vp.push_back(p4);
reverse(vp.begin(),vp.end());
for_each(vp.begin(),vp.end(),printperson);
cout << endl;
}
4 常用拷贝和替换算法
1 copy
//拷贝和替换
void myprint(int val)
{
cout << val << " ";
}
//内置数据类型
void test01()
{
vector<int> v1;
for(int i=0;i<9;i++)
{
v1.push_back(i);
}
vector<int> v2;
v2.resize(v1.size());
copy(v1.begin(),v1.end(),v2.begin());
for_each(v2.begin(),v2.end(),myprint);
cout << endl;
}
2 替换
在一个区间的满足条件的值都会替换
//仿函数
class Myprint
{
public:
void operator()(int val)
{
cout << val << " ";
}
};
//内置数据类型
void test01()
{
vector<int> v1;
for(int i=0;i<9;i++)
{
v1.push_back(i%2);
}
replace(v1.begin(),v1.end(),0,200);
for_each(v1.begin(),v1.end(),Myprint());
cout << endl;
}
3.按条件替换
class greater5
{
public:
bool operator()(int val)
{
return val > 5;
}
};
//内置数据类型
void test01()
{
vector<int> v1;
for(int i=0;i<9;i++)
{
v1.push_back(i);
}
replace_if(v1.begin(),v1.end(),greater5(),200);
for_each(v1.begin(),v1.end(),Myprint());
cout << endl;
}
我自己的写的自定义数据
//自定义数据?
class person
{
public:
person(string name,int age)
{
this->m_name = name;
this->m_age = age;
}
void operator=(const person& p)
{
this->m_age = p.m_age;
this->m_name = p.m_name;
}
string m_name;
int m_age;
};
class greater11
{
public:
bool operator()(const person&p)
{
return p.m_age > 11;
}
};
void printperson(const person &p)
{
cout << p.m_name << " " << p.m_age << " ";
}
void test02()
{
vector<person> vp;
person p1("a",10);
person p2("b",11);
person p3("c",12);
person p4("d",13);
vp.push_back(p1);
vp.push_back(p2);
vp.push_back(p3);
vp.push_back(p4);
person pp("a",100);
replace_if(vp.begin(),vp.end(),greater11(),pp);
for_each(vp.begin(),vp.end(),printperson);
cout << endl;
}
4 SWAP
swap的两个容器必须是相同类型
//仿函数
class Myprint
{
public:
void operator()(int val)
{
cout << val << " ";
}
};
class greater5
{
public:
bool operator()(int val)
{
return val > 5;
}
};
//内置数据类型
void test01()
{
vector<int> v1;
for(int i=0;i<9;i++)
{
v1.push_back(i);
}
vector<int> v2;
for(int i=100;i<109;i++)
{
v2.push_back(i);
}
swap(v1,v2);
for_each(v1.begin(),v1.end(),Myprint());
cout << endl;
}
5 常用算数生成算法
1 accumulate
需要包含头文件<numeric>
//内置数据类型
void test01()
{
vector<int> v1;
for(int i=0;i<9;i++)
{
v1.push_back(i);
}
int sum = accumulate(v1.begin(),v1.end(),0);//0 起始累加值
cout << sum << endl;
}
2 fill填充
后期填充
//内置数据类型
void test01()
{
vector<int> v1;
v1.resize(10);
//重新填充操作
fill(v1.begin(),v1.end(),100);
// for(int i=0;i<9;i++)
// {
// v1.push_back(i);
// }
for_each(v1.begin(),v1.end(),myprint);
}
6 常用集合算法
两个源容器必须是有序序列
返回值都是目标容器的集合尾端迭代器
1.set_intersection
目标容器的大小 极端值的情况下就是 一个大容器包含一个小容器,所以取值取小容器的SIZE
set_intersection的返回值是交际中最后一个元素的位置
//内置数据类型
void test01()
{
vector<int> v1;
for(int i=0;i<9;i++)
{
v1.push_back(i);
}
vector<int> v2;
for(int i=5;i<14;i++)
{
v2.push_back(i);
}
vector<int> v3;
//最特殊的情况,就是 大容器包含小容器,取空间取小容器
v3.resize(max(v1.size(),v2.size()));
vector<int>::iterator itEnd = set_intersection(v1.begin(),v1.end(),v2.begin(),v2.end(),v3.begin());
cout << *itEnd << endl;
for_each(v3.begin(),itEnd,myprint);
}
2 set_union
//内置数据类型
void test01()
{
vector<int> v1;
for(int i=0;i<9;i++)
{
v1.push_back(i);
}
vector<int> v2;
for(int i=5;i<14;i++)
{
v2.push_back(i);
}
vector<int> v3;
v3.resize(v1.size()+v2.size());
vector<int>::iterator itEnd = set_union(v1.begin(),v1.end(),v2.begin(),v2.end(),v3.begin());
cout << *itEnd << endl;
for_each(v3.begin(),itEnd,myprint);
}
3 set_difference
//仿函数
class Myprint
{
public:
void operator()(int val)
{
cout << val << " ";
}
};
//内置数据类型
void test01()
{
vector<int> v1;
for(int i=0;i<9;i++)
{
v1.push_back(i);
}
cout << "--v1--"<<endl;
for_each(v1.begin(),v1.end(),myprint);
cout << endl;
vector<int> v2;
for(int i=5;i<14;i++)
{
v2.push_back(i);
}
cout << "--v2--"<<endl;
for_each(v2.begin(),v2.end(),myprint);
cout << endl;
cout << "---v1 VS v2 difference----"<< endl;
vector<int> v3;
v3.resize(v1.size());
vector<int>::iterator itEnd = set_difference(v1.begin(),v1.end(),v2.begin(),v2.end(),v3.begin());
for_each(v3.begin(),itEnd,myprint);
cout << endl;
cout << "---v2 VS v1 difference----"<< endl;
vector<int> v4;
v4.resize(v2.size());
vector<int>::iterator itEnd2 = set_difference(v2.begin(),v2.end(),v1.begin(),v1.end(),v4.begin());
for_each(v4.begin(),itEnd2,myprint);
cout << endl;
}
输出:
--v1--
0 1 2 3 4 5 6 7 8
--v2--
5 6 7 8 9 10 11 12 13
---v1 VS v2 difference----
0 1 2 3 4
---v2 VS v1 difference----
9 10 11 12 13