当前位置: 首页 > news >正文

STL常用算法——C++

1.概述

2.常用遍历算法

1.简介

2.for_each

方式一:传入普通函数(printf1)

#include<stdio.h>
using namespace std;
#include<string>
#include<vector>
#include<functional>
#include<algorithm>
#include <iostream>
void printf1(int a)
{cout << a << " ";
}
int main()
{vector<int> v;for (int i = 0; i < 10; i++){v.push_back(i);}for_each(v.begin(), v.end(), printf1);cout << endl;return 0;
}

方式2:利用仿函数,传入匿名函数对象

#include<stdio.h>
using namespace std;
#include<string>
#include<vector>
#include<functional>
#include<algorithm>
#include <iostream>
class person
{
public:void operator()(int a){cout << a << " ";}
};
int main()
{vector<int> v;for (int i = 0; i < 10; i++){v.push_back(i);}for_each(v.begin(), v.end(), person());cout << endl;return 0;
}

注意:函数只需要传入函数名就行,但是仿函数需要传入函数对象。

for_each在实际开发中是最常用的一个算法,需要熟练掌握

3.transform

#include<stdio.h>
using namespace std;
#include<string>
#include<vector>
#include<functional>
#include<algorithm>
#include <iostream>
class transform1
{
public:int operator()(int a){return a;}
};
class print
{
public:void operator()(int a){cout<<a<<" ";}
};
int main()
{vector<int> v;for (int i = 0; i < 10; i++){v.push_back(i);}vector<int>v1;v1.resize(v.size());transform(v.begin(), v.end(), v1.begin(), transform1());for_each(v.begin(), v.end(), print());cout << endl;return 0;
}

注意:转运之前,需要将目标对象用resize()也开辟相同的空间。

3.常用查找算法

1.find

#include<stdio.h>
using namespace std;
#include<string>
#include<vector>
#include<functional>
#include<algorithm>
#include <iostream>
class person
{
public:person(string name, int age){this->name = name;this->age = age;}bool operator==(const person& p){if (this->age == p.age && this->name == p.name){return true;}else return false;}string name;int age;
};
int main()
{vector<person> v;person p1("1", 12);person p2("2", 13);person p3("3", 14);person p4("4", 15);person p5("5", 16);v.push_back(p1);v.push_back(p2);v.push_back(p3);v.push_back(p4);v.push_back(p5);vector<person>::iterator it = find(v.begin(), v.end(), p2);if (it == v.end()){cout << "没有找到" << endl;}else{cout << "找到了" << endl;}return 0;
}

或者也可以将查找条件改为

    person pp(”11“,13);

    vector<person>::iterator it = find(v.begin(), v.end(), pp);

注意:find的返回值是迭代器

2.find_if

#include<stdio.h>
using namespace std;
#include<string>
#include<vector>
#include<functional>
#include<algorithm>
#include <iostream>
class person
{
public:bool operator()(int val){return val > 5;}
};
int main()
{vector<int> v;for (int i = 0; i < 10; i++){v.push_back(i);}vector<int>::iterator it=find_if(v.begin(), v.end(), person());if (it == v.begin()){cout << "没有找到" << endl;}else{cout << "找到了:" << *it << endl;}return 0;
}

3.abjacent_find

#include<stdio.h>
using namespace std;
#include<string>
#include<vector>
#include<functional>
#include<algorithm>
#include <iostream>
int main()
{vector<int> v;v.push_back(1);v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(3);v.push_back(4);vector<int>::iterator it=adjacent_find(v.begin(), v.end());if (it == v.end()){cout << "没有找到" << endl;}else{cout << "找到了:" << *it << endl;}return 0;
}

4.binary_search

底层原理就是二分查找,二分查找需要提前排序好才能用,二分查找需要的算力少。

#include<stdio.h>
using namespace std;
#include<string>
#include<vector>
#include<functional>
#include<algorithm>
#include <iostream>
int main()
{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){cout << "找到了" << endl;}else{cout << "没找到" << endl;}return 0;
}

如果是无序序列,结果未知

5.count

#include<stdio.h>
using namespace std;
#include<string>
#include<vector>
#include<functional>
#include<algorithm>
#include <iostream>
class person
{
public:person(string name, int age){this->age = age;this->name = name;}bool operator==(const person& p){if (p.age == this->age){return true;}else{return false;}}int age;string name;
};
int main()
{vector<person> v;person p1("刘备", 35);person p2("关羽", 35);person p3("张飞", 35);person p4("赵云", 20);person p5("刘备", 40);v.push_back(p1);v.push_back(p2);v.push_back(p3);v.push_back(p4);v.push_back(p5);person p("诸葛亮", 35);int a = count(v.begin(), v.end(), p);cout << "同年龄的有:" << a << "个" << endl;return 0;
}

关于为什么operator要加const

const Person p1("刘备", 35);

Person p2("关羽", 35);

if (p1 == p2)

{

// 编译错误:无法将 const 对象传递给非 const 引用参数

cout << "年龄相同" << endl;

}

在运算符重载中,参数通常也会被声明为const。这样做的目的是为了扩大函数的适用范围,使其既能接受const对象,也能接受非const对象。

总结:对于统计自定义数据类型的时候,需要配合重载operator==

           对于形参是自定义类型时,要加上const

6.count_if

#include<stdio.h>
using namespace std;
#include<string>
#include<vector>
#include<functional>
#include<algorithm>
#include <iostream>
class person
{
public:bool operator()(int val){return val == 2;}
};
int main()
{vector<int> v;v.push_back(1);v.push_back(2);v.push_back(2);v.push_back(2);v.push_back(5);int a = count_if(v.begin(), v.end(), person());cout << "同年龄的有:" << a << "个" << endl;return 0;
}

4.常用排序算法

1.sort

pred是谓词

生序

#include<stdio.h>
using namespace std;
#include<string>
#include<vector>
#include<functional>
#include<algorithm>
#include <iostream>
void print(int a)
{cout << a << " ";
}
int main()
{vector<int> v;v.push_back(1);v.push_back(2);v.push_back(6);v.push_back(3);v.push_back(5);sort(v.begin(), v.end());for_each(v.begin(), v.end(), print);return 0;
}

降序(利用内建函数对象greater实现降序排序,要包含头文件functional)

#include<stdio.h>
using namespace std;
#include<string>
#include<vector>
#include<functional>
#include<algorithm>
#include <iostream>
void fun(int a)
{cout << a << " ";
}
int main()
{vector<int> v;v.push_back(1);v.push_back(2);v.push_back(6);v.push_back(3);v.push_back(5);sort(v.begin(), v.end(), greater<int>());for_each(v.begin(), v.end(),fun);return 0;
}

2.random_shuffle

#include<stdio.h>
using namespace std;
#include<string>
#include<vector>
#include<functional>
#include<algorithm>
#include <iostream>
void fun(int a)
{cout << a << " ";
}
int main()
{vector<int> v;for (int i = 0; i < 10; i++){v.push_back(i);}random_shuffle(v.begin(), v.end());for_each(v.begin(), v.end(),fun);return 0;
}

可以加入时间种子来达到真随机效果(srand(unsigned int)time(NULL);)

不过需要包含头文件#include<time.h>

3.merge

#include<stdio.h>
using namespace std;
#include<string>
#include<vector>
#include<functional>
#include<algorithm>
#include <iostream>
void fun(int a)
{cout << a << " ";
}
int main()
{vector<int> v1;vector<int> v2;vector<int> v3;for (int i = 0; i < 10; i++){v1.push_back(i);v2.push_back(i+1);}v3.resize(v1.size() + v2.size());merge(v1.begin(), v1.end(), v2.begin(), v2.end(), v3.begin());for_each(v3.begin(), v3.end(),fun);return 0;
}

不过要给目标容器提前开辟内存空间用resize

而且合并之后还是一个有序序列

merge合并的两个序列必须是有序序列

4.reverse

5.常用拷贝和替换算法

1.copy

#include<stdio.h>
using namespace std;
#include<string>
#include<vector>
#include<functional>
#include<algorithm>
#include <iostream>
void fun(int a)
{cout << a << " ";
}
int main()
{vector<int> v1;vector<int> v2;for (int i = 0; i < 10; i++){v1.push_back(i);}v2.resize(v1.size());copy(v1.begin(), v1.end(), v2.begin());for_each(v2.begin(), v2.end(),fun);return 0;
}

2.replace

3.replace_if

#include<stdio.h>
using namespace std;
#include<string>
#include<vector>
#include<functional>
#include<algorithm>
#include <iostream>
void fun(int a)
{cout << a << " ";
}
class person
{
public:bool operator()(int val){return val > 5;}
};
int main()
{vector<int> v1;for (int i = 0; i < 10; i++){v1.push_back(i);}replace_if(v1.begin(), v1.end(), person(), 1000);for_each(v1.begin(), v1.end(),fun);return 0;
}

可以利用仿函数灵活的设置筛选条件

4.swap

swap(v1,v2);

其中两个容器的大小和数值都会交换,不过交换的容器要同种类型

6.常用算术生成算法

1.accumulate

#include<stdio.h>
using namespace std;
#include<string>
#include<vector>
#include<functional>
#include<algorithm>
#include <iostream>
#include<numeric>
void fun(int a)
{cout << a << " ";
}
class person
{
public:bool operator()(int val){return val > 5;}
};
int main()
{vector<int> v1;for (int i = 0; i <= 100; i++){v1.push_back(i);}int val=accumulate(v1.begin(),v1.end(),0);/*for_each(v1.begin(), v1.end(),fun);*/cout << val << endl;return 0;
}

比较实用,记住要添加头文件#include<numeric>

2.fill

#include<stdio.h>
using namespace std;
#include<string>
#include<vector>
#include<functional>
#include<algorithm>
#include <iostream>
#include<numeric>
void fun(int a)
{cout << a << " ";
}
class person
{
public:bool operator()(int val){return val > 5;}
};
int main()
{vector<int> v1;for (int i = 0; i < 10; i++){v1.push_back(i);}fill(v1.begin(),v1.end(),99);for_each(v1.begin(), v1.end(),fun);cout << endl;vector<int> v2;v2.resize(10);fill(v2.begin(), v2.end(), 11);for_each(v2.begin(), v2.end(), fun);return 0;
}

如果已经有了数值,会把原来的数值顶替掉

7.常用集合算法

1.set_intersection

交集:即两个容器中数值相同的元素

#include<stdio.h>
using namespace std;
#include<string>
#include<vector>
#include<functional>
#include<algorithm>
#include <iostream>
#include<numeric>
void fun(int a)
{cout << a << " ";
}
class person
{
public:bool operator()(int val){return val > 5;}
};
int main()
{vector<int> v1;vector<int> v2;for (int i = 0; i < 10; i++){v1.push_back(i);v2.push_back(i+3);}vector<int>v3;v3.resize(min(v1.size(), v2.size()));vector<int>::iterator it=set_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(), v3.begin());for_each(v3.begin(),it,fun);cout << endl;return 0;
}

注意:

set_intersection其中它会返回交际的最后一个元素的迭代器,遍历输出交集的时候不要写end(),要写它返回的迭代器,这样就不会输出无用元素。

存储交集的目标容器需要提前开辟空间,最特殊的情况是大容器包含小容器,即交集就是小容器,所以取小容器的大小即可。

min()包含在algorithm头文件中,找出最小值

2.set_union

#include<stdio.h>
using namespace std;
#include<string>
#include<vector>
#include<functional>
#include<algorithm>
#include <iostream>
#include<numeric>
void fun(int a)
{cout << a << " ";
}
class person
{
public:bool operator()(int val){return val > 5;}
};
int main()
{vector<int> v1;vector<int> v2;for (int i = 0; i < 10; i++){v1.push_back(i);v2.push_back(i+3);}vector<int>v3;v3.resize(v1.size()+v2.size());vector<int>::iterator it=set_union(v1.begin(), v1.end(), v2.begin(), v2.end(), v3.begin());for_each(v3.begin(),it,fun);cout << endl;return 0;
}

最坏的情况是一个相同的都没有,所以开辟大小直接把两个容器的大小加起来就行

注意:两个容器必须是有序序列

3.set_different

有两种差集的情况:(谁在前先求谁的差集)

#include<stdio.h>
using namespace std;
#include<string>
#include<vector>
#include<functional>
#include<algorithm>
#include <iostream>
#include<numeric>
void fun(int a)
{cout << a << " ";
}
class person
{
public:bool operator()(int val){return val > 5;}
};
int main()
{vector<int> v1;vector<int> v2;for (int i = 0; i < 10; i++){v1.push_back(i);v2.push_back(i+3);}v2.push_back(99);vector<int>v3;v3.resize(max(v1.size(),v2.size()));vector<int>::iterator it=set_difference(v1.begin(), v1.end(), v2.begin(), v2.end(), v3.begin());for_each(v3.begin(),it,fun);cout << endl;vector<int>::iterator it1 = set_difference(v2.begin(), v2.end(), v1.begin(), v1.end(), v3.begin());for_each(v3.begin(), it1, fun);cout << endl;return 0;
}

注意:两个容器必须是有序序列

http://www.xdnf.cn/news/77869.html

相关文章:

  • WPF特性分析
  • Java面向对象的三大特性
  • CAD在线查看免费,可以支持DWG/GLB/GLTF/doc/wps/pdf/psd/eml/zip, rar/MP3/MP4/svg/OBJ/FBX格式
  • 代理设计模式:从底层原理到源代码的详细解释
  • 性能比拼: Redis vs Dragonfly
  • 机器学习第一篇 线性回归
  • 《剥开卷积神经网络CNN的 “千层酥”:从基础架构到核心算法》
  • Prompt工程:大模型的「精准导航系统」
  • 从零开始构建微博爬虫与数据分析系统
  • WebRTC服务器Coturn服务器部署
  • Java求职面试:从Spring Boot到微服务的全面考核
  • 静态时序分析STA——8.6-7 时序检查(撤销时间和恢复时间)
  • 【系统架构设计师】嵌入式微处理器
  • 云原生--基础篇-4--CNCF-1-云原生计算基金会(云原生生态发展和目标)
  • 3、有Bluetooth,LCD,USB,SD卡,PSRAM,FLASH、TP等软硬件驱动开发经验优先考虑
  • ffmpeg av_buffer_unref的逻辑实现; av_freep 和 av_freep函数的区别
  • Vue3+TS中svg图标的使用-@unocss/preset-icons
  • Java面试实战:从Spring Boot到微服务的深入探讨
  • 云账号安全事件应急响应指南:应对来自中国IP的异常访问
  • 测试OMS(订单管理系统)时,对Elasticsearch(ES)数据和算法数据进行测试(如何测试几百万条数据)
  • 画布交互系统深度优化:从动态缩放、小地图到拖拽同步的全链路实现方案
  • js原型链prototype解释
  • 利用java语言,怎样开发和利用各种开源库和内部/自定义框架,实现“提取-转换-加载”(ETL)流程的自动化
  • 01.浏览器自动化webdriver源码分析之启动函数
  • 基于Python+Pytest实现自动化测试(全栈实战指南)
  • 热敏电阻的应用说明
  • Rest Client插件写http文件直接发送请求
  • 复盘20250422
  • Maven集成模块打包使用
  • Shell脚本中的字符串截取和规则变化