这一期就是我们STL基本学习的最后一期了~~完结撒花~
前期系列内容回顾:
大话STL第一期——初识相见恨晚 |
大话STL第二期——机械先驱—vector |
大话STL第三期——deque(双端动态数组 |
大话STL第四期——list双向链表 |
大话STL第五期——set/multiset(含pair对组) |
大话STL第六期——map/multimap |
大话STL第七期——stack栈 |
大话STL第八期——queue队列 |
大话STL第九期——仿函数(函数对象) |
关注主页不迷路:
Oorik的博客_CSDN博客-C,C++领域博主
文章篇幅较长,我会根据功能分类进行演示和总结,可以跳转自己需要的地方
文章目录
find:按值查找元素,找到返回指定位置迭代器,找不到返回结束迭代器位置
adjacent_find:查找相邻重复元素,返回相邻元素的第一个位置的迭代器
binary_search:查找指定元素是否存在,查到返回true,否则返回false
random_shuffle:洗牌打乱顺序,指定范围内的元素随机调整次序
replace-if:将区间内满足条件的元素,替换成指定元素
accumulate(求累加):将它的一个内部变量设置为指定的初始值,然后在此初值上累加输入范围内所有元素的值
set_intersection:求两个集合的交集,源容器必须有序,目标容器开辟取两个源容器较小的
set_union:求两个集合的并集,源容器必须有序,目标容器开辟取两个源容器之和
set_difference:求两个集合的差集,源容器必须有序,目标容器开辟取两个源容器较大的
STL常用算法概述:
算法主要是由头文件<algorithm> <functional> <numeric>组成
<algorithm>是所有STL头文件中最大的一个,范围涉及到比较、交换、查找、遍历、赋值、修改等等
<functional> 定义了一些模板类。用以声明函数对象
<numeric>体积很小,只包括几个在序列上面进行简单教学运算的模板函数
常用遍历算法:
for_each:遍历容器元素
函数原型:for_each(iterator beg,iterator end, _func);
beg开始迭代器
end结束迭代器
_func函数或者函数对象
void show(string a)//利用函数
{
cout << a << " " << endl;
}
class A { //利用函数对象
public:
void operator ()(string a)
{
cout << a << " " << endl;
}
};
int main()
{
vector<string> vv{ "OK","张三","李四" };
for_each(vv.begin(), vv.end(), show);
cout << "---------------" << endl;
for_each(vv.begin(), vv.end(),A());
return 0;
}
transform:搬用容器到另一个容器中
函数原型:for_each(iterator beg1,iterator end1,interator beg2 ,_func);
beg1源开始迭代器
end1源结束迭代器
beg2目标容器开始迭代器
_func函数或者函数对象
void show(int a)
{
cout << a << " " << endl;
}
class TT{
public:
int operator ()(int a)
{
return a;
}
};
int ok(int a)
{
return a + 100;
}
int main()
{
vector<int> vv;//源容器
for (int i = 0; i < 10; ++i)
{
vv.push_back(i + 1);
}
vector<int> vg;//目标容器 这样构造没有容量
vg.resize(vv.size());//目标容器需要开辟空间
//正常的搬运 利用函数对象方式
transform(vv.begin(), vv.end(), vg.begin(), TT());
for_each(vg.begin(), vg.end(), show);
cout << "------------------------" << endl;
//边搬运边计算,因此要重写相对应的逻辑函数或者函数对象
transform(vv.begin(), vv.end(), vg.begin(), ok);//利用函数
for_each(vg.begin(), vg.end(), show);
return 0;
}
常用查找算法:
find:按值查找元素,找到返回指定位置迭代器,找不到返回结束迭代器位置
函数原型:find(iterator beg,iterator end,value);
beg开始迭代器
end结束迭代器
value所要查找的元素
class TT{
private:
string name;
int age;
public:
TT(string name, int age) :name(name), age(age) {
}
string Getname(){
return this->name;
}
int Getage() {
return this->age;
}
//重载== 让底层find如何对比自定义数据类型
bool operator==(const TT& t)
{
if (this->name == t.name && this->age == t.age)
{
return true;
}
else
return false;
}
};
int main()
{
vector<TT> vv{ {"aa",3},{"bb",4},{"cc",5} };
TT pp("cc", 5);
auto it = find(vv.begin(), vv.end(),pp);
if (it == vv.end())
{
cout << "没有找到" << endl;
}
else
cout << "找到了" << it->Getname()<<" "<<it->Getage()<<endl;
return 0;
}
find_if:按条件查找元素
函数原型:find(iterator beg,iterator end,pred);
beg开始迭代器
end结束迭代器
pred函数或者谓词(返回bool类型的仿函数)
class TT{
private:
string name;
int age;
public:
TT(string name, int age) :name(name), age(age) {
}
string Getname()const{
return this->name;
}
int Getage()const {
return this->age;
}
};
//函数对象找age大于3的人
class AA {
public:
bool operator()( const TT& t)
{
if (t.Getage() > 3)
{
return true;
}
else
return false;
}
};
int main()
{
vector<TT> vv{ {"aa",3},{"bb",4},{"cc",5} };
auto it = find_if(vv.begin(), vv.end(),AA());
for(;it != vv.end();it++)
{
if(it == vv.end())
{
cout << "没有找到" << endl;
}
else
cout << "找到了" << it->Getname()<<" "<<it->Getage()<<endl;
}
return 0;
}
adjacent_find:查找相邻重复元素,返回相邻元素的第一个位置的迭代器
函数原型:adjacent_find(interator beg,interator end)
beg开始迭代器
end结束迭代器
int main()
{
vector<int> vv{1,2,3,4,5,5,6 };
auto it = adjacent_find(vv.begin(), vv.end());
if(it == vv.end())
{
cout << "没有找到" << endl;
}
else
cout << "找到了" <<*it<<endl;
return 0;
}
binary_search:查找指定元素是否存在,查到返回true,否则返回false
函数原型:bool binary_serach(interator beg,interator end,value)
注意:在无序序列中不可用
beg开始迭代器
end结束迭代器
value所要查找的元素
int main()
{
vector<int> vv{1,2,3,4,5,5,6 };
if (binary_search(vv.begin(), vv.end(), 7) == 1)
cout << "找到了" << endl;
else
cout << "没有找到" << endl;
return 0;
}
count:统计元素个数
函数原型:count(interator beg,interator end,value)
beg开始迭代器
end结束迭代器
value所要查找的元素
class TT {
public:
string name;
int age;
TT(string name, int age) :name(name), age(age) {
}
bool operator==(const TT& t)
{
if (name == t.name && age == t.age)
{
return true;
}
else
return false;
}//统计自定义数据类型时候需要配合重载的operator==
};
int main()
{
vector<int> vv{1,2,3,4,5,5,6 };
int n = count(vv.begin(), vv.end(), 5);//统计5出现的次数
cout << n << endl;
vector<TT> vm{ {"刘备",3},{"张飞",4} };
TT t1{ "张飞",4 };
int m = count(vm.begin(), vm.end(), t1);
cout << m << endl;
return 0;
}
count_if:按条件统计元素个数
函数原型:count_if(interator beg,interator end,pred)
beg开始迭代器
end结束迭代器
pred条件谓词(bool仿函数)
class TT {
public:
string name;
int age;
TT(string name, int age) :name(name), age(age) {
}
};
class AA {
public:
bool operator()(const TT& t)
{
if (t.age > 1)//统计年龄大于1的
return true;
else
return false;
}
};
class BB {
public:
bool operator()(int b)
{
return b > 2;
}
};
int main()
{
vector<int> vv{1,2,3,4,5,5,6 };
int n = count_if(vv.begin(), vv.end(), BB());//统计大于2的个数
cout << n << endl;
vector<TT> vm{ {"刘备",3},{"张飞",4} };
int m = count_if(vm.begin(), vm.end(), AA());//统计年龄大于1的
cout << "年龄大于1的人有:" << m <<endl;
return 0;
}
常用排序算法:
sort:对容器内部进行排序
函数原型:sort(interator beg,interator end,pred)
beg开始迭代器
end结束迭代器
pred条件谓词(bool仿函数)
void mprint(int a)
{
cout << a << " ";
}
int main()
{
vector<int> vv{1,3,10,11,2,4,5,3,4,5,4 };
sort(vv.begin(), vv.end());//默认升序
for (int i = 0; i < vv.size(); ++i)
{
cout << vv[i] << " ";
}
cout << endl;
//改为升序,利用STL内置的仿函数
sort(vv.begin(), vv.end(),greater<>());
//利用for_each打印
for_each(vv.begin(), vv.end(), mprint);
return 0;
}
random_shuffle:洗牌打乱顺序,指定范围内的元素随机调整次序
函数原型:random_shuffle(interator beg,interator end)
beg开始迭代器
end结束迭代器
void mprint(int a)
{
cout << a << " ";
}
int main()
{
srand((unsigned int)time(NULL));
vector<int> vv{1,2,3,4,5,6,7,8 };
//利用洗牌算法打乱顺序,但是每次打乱结果都是一样的
//如果需要真的随机,那就需要添加随机种子
random_shuffle(vv.begin(), vv.end());
for_each(vv.begin(), vv.end(), mprint);
return 0;
}
merge:两个容器元素合并,并存储到另一个容器中
注意:两个容器必须是有序的,且合并之后同样有序
函数原型:merge(interator beg1,interator end1,interator beg2,interator end2,interator dest)
beg1 容器1开始迭代器
end1 容器1结束迭代器
beg2 容器2开始迭代器
end2 容器2结束迭代器
dest 目标容器开始迭代器
void mprint(int a)
{
cout << a << " ";
}
int main()
{
vector<int> vv{1,2,3,4,5,6,7,8 };//源容器1
vector<int> vm{ 2,4,5,8 ,10,14,25};//源容器2
vector<int> vx;//目标容器
vx.resize(vv.size() + vm.size());//分配空间
merge(vv.begin(), vv.end(), vm.begin(), vm.end(), vx.begin());
for_each(vx.begin(), vx.end(), mprint);
return 0;
}
reverse:将容器内元素进行反转
函数原型:reverse(interator beg,interator end)
beg开始迭代器
end结束迭代器
void mprint(int a)
{
cout << a << " ";
}
int main()
{
vector<int> vv{1,2,3,4,5,6,7,8 };//源容器1
cout << "反转前:" << endl;
for_each(vv.begin(), vv.end(), mprint);
cout << endl;
cout << "反转后:" << endl;
reverse(vv.begin(), vv.end());
for_each(vv.begin(), vv.end(), mprint);
return 0;
}
常用的拷贝和替换算法:
copy:容器内指定元素拷贝到另一容器
函数原型:copy(interator beg,interator end,interator dest)
beg源容器开始迭代器
end源容器结束迭代器
dest目标容器开始拷贝位置的迭代器
void mprint(int a)
{
cout << a << " ";
}
int main()
{
vector<int> vv{1,2,3,4,5,6,7,8 };//源容器
vector<int>vx(15, 2);//目标容器
//开辟了15 个2 ,源容器元素少拷贝到目标容器后
//前面的元素改变,后面依然是2
//如果目标容器容量小或者没有,需要申请容量
copy(vv.begin(), vv.end(), vx.begin());
for_each(vx.begin(), vx.end(), mprint);
return 0;
}
replace:将容器指定范围内的旧元素修改为新元素
replace(interator beg,interator end,oldvalue,newvalue)
beg开始迭代器
end结束迭代器
oldvalue旧元素
newvalue新元素
int main()
{
vector<int> vv{1,2,5,5,4,5,5,6,7,8 };
replace(vv.begin() + 2, vv.end(), 5, 50);
//将2下标到end区间的5都换成50 ,begin和end是左闭右开的区间
for (auto it = vv.begin(); it != vv.end(); it++)
{
cout << (*it) << " ";
}
return 0;
}
replace-if:将区间内满足条件的元素,替换成指定元素
replace_if(interator beg,interator end,pred,newvalue)
beg开始迭代器
end结束迭代器
pred 谓词
newvalue替换的新元素
class Pred { //仿函数
public:
bool operator()(string name)
{
return name == "张三";
}
};
bool AA(string name)//普通自定义函数
{
return name == "张三";
}
int main()
{
vector<string>vv;
vv.push_back("张三");
vv.push_back("李四");
vv.push_back("张三");
vv.push_back("李四");
vv.push_back("张三");
//将张三全部替换为王五
replace_if(vv.begin(), vv.end(), Pred(), "王五");//调用的仿函数,也可以调用普通函数AA
for (auto it = vv.begin(); it != vv.end(); it++)
{
cout << (*it) << " ";
}
return 0;
}
swap:互换两个同种类型容器的元素
swap(container c1 ,container c2);
c1 容器
c2容器
void show(vector<int>&v1)
{
for (auto it = v1.begin(); it != v1.end(); it++)
{
cout << (*it) << " ";
}
cout << endl;
}
int main()
{
vector<int>v1{5,5,1,2,4,5};
vector<int>v2{ 1,2,3,4,5,6,7,8,9,10 };
cout << "v1交换前:" << endl;
show(v1);
cout << "v2交换前:" << endl;
show(v2);
cout << "------------------------------" << endl;
swap(v1, v2);
// v1.swap(v2);使用vector内置的swap交换
cout << "v1交换后:" << endl;
show(v1);
cout << "v2交换后:" << endl;
show(v2);
}
常用的算数生成算法:
accumulate(求累加):将它的一个内部变量设置为指定的初始值,然后在此初值上累加输入范围内所有元素的值
函数原型:accumulate(interator beg,interator end,value);
beg 开始迭代器
end 结束迭代器
value 和的起始值
int main()
{
vector<int>vv{ 1,2,3,4,5,6,7,8,9,10 };
int n = accumulate(vv.begin(), vv.end(),100);
cout << n << endl;//155,因为内部起始值设置的是100
return 0;
}
fill:对容器实现指定元素的填充
函数原型:fill(interator beg,interator end,value);
beg 开始迭代器
end 结束迭代器
value 填充的值
void show(vector<int>&v1)
{
for (auto it = v1.begin(); it != v1.end(); it++)
{
cout << (*it) << " ";
}
cout << endl;
}
int main()
{
vector<int>vv(10, 1);//初始化10个1
fill(vv.begin(), vv.begin() + 5, 2);//前5个填充为2
show(vv);
return 0;
}
常用的集合算法:
set_intersection:求两个集合的交集,源容器必须有序,目标容器开辟取两个源容器较小的
函数原型:set_intersection(interator beg1,interator end1,interator beg2,interator end2,interator dest)
beg1容器1的开始迭代器
end1容器1的结束迭代器
beg2容器2的开始迭代器
end2容器2的结束迭代器
dest目标容器的开始迭代器
set_union
void show(vector<int>&v1)
{
for (auto it = v1.begin(); it != v1.end(); it++)
{
cout << (*it) << " ";
}
cout << endl;
}
int main()
{
vector<int>vv{ 0,1,2,3,4,5,6,7,8,9 };//容器1
vector<int>vvm{ 6,7,8,9,10,11,12 };//容器2
vector<int>vmx;//目标容器
vmx.resize(min(vv.size(),vvm.size()));//开辟空间,取小容器大小
set_intersection(vv.begin(), vv.end(), vvm.begin(), vvm.end(), vmx.begin());
show(vmx);//会遍历所有数据将交集数据以及后面申请空间默认的0都打印出来
//6 7 8 9 0 0 0
//返回交集结束的迭代器
auto is= set_intersection(vv.begin(), vv.end(), vvm.begin(), vvm.end(), vmx.begin());
//输出
for (auto im=vmx.begin();im!=is;im++)
{
cout << (*im) << " ";//6 7 8 9
}
return 0;
}
set_union:求两个集合的并集,源容器必须有序,目标容器开辟取两个源容器之和
函数原型:set_union(interator beg1,interator end1,interator beg2,interator end2,interator dest)
beg1容器1的开始迭代器
end1容器1的结束迭代器
beg2容器2的开始迭代器
end2容器2的结束迭代器
dest目标容器的开始迭代器
void show(vector<int>&v1)
{
for (auto it = v1.begin(); it != v1.end(); it++)
{
cout << (*it) << " ";
}
cout << endl;
}
int main()
{
vector<int>vv{ 1,2,3,4,4,5,6,7,7};//容器1
vector<int>vvm{ 6,7,8,9,10,11,12 };//容器2
vector<int>vmx;//目标容器
vmx.resize(vv.size()+vvm.size());
set_union(vv.begin(), vv.end(), vvm.begin(), vvm.end(), vmx.begin());
show(vmx);//会遍历所有数据将并集数据以及(如果空间有剩余)后面申请空间默认的0都打印出来
//返回并集结束的迭代器
auto is= set_union(vv.begin(), vv.end(), vvm.begin(), vvm.end(), vmx.begin());
//输出
for (auto im=vmx.begin();im!=is;im++)
{
cout << (*im) << " ";
}
return 0;
}
set_difference:求两个集合的差集,源容器必须有序,目标容器开辟取两个源容器较大的
函数原型:set_difference(interator beg1,interator end1,interator beg2,interator end2,interator dest)
beg1容器1的开始迭代器
end1容器1的结束迭代器
beg2容器2的开始迭代器
end2容器2的结束迭代器
dest目标容器的开始迭代器
void show(vector<int>&v1)
{
for (auto it = v1.begin(); it != v1.end(); it++)
{
cout << (*it) << " ";
}
cout << endl;
}
int main()
{
vector<int>vv{ 1,2,3,4,4,5,6,7,7};//容器1
vector<int>vvm{ 6,7,8,9,10,11,12 };//容器2
vector<int>vmx;//目标容器
vmx.resize(max(vv.size(),vvm.size()));//最特殊的情况取最大的
set_difference(vv.begin(), vv.end(), vvm.begin(), vvm.end(), vmx.begin());
show(vmx);//会遍历所有数据将差集数据以及(如果空间有剩余)后面申请空间默认的0都打印出来
//返回并集结束的迭代器
auto is= set_difference(vv.begin(), vv.end(), vvm.begin(), vvm.end(), vmx.begin());
//输出
for (auto im=vmx.begin();im!=is;im++)
{
cout << (*im) << " ";
}
return 0;
}
STL系列基础更新到这里就结束了,有兴趣订阅专栏,收藏学习。