C++之常用的算法
1 函数对象
重载函数调用运算符的类,其对象称为函数对象。
一元仿函数 / 二元仿函数(根据参数个数判定)
| class MyPrint { |
| public: |
| void operator() (int num) { |
| cout << "num = " << num << endl; |
| } |
| }; |
| |
| void test01() { |
| MyPrint myPrint; |
| myPrint(2); |
| } |
| class MyPrint { |
| public: |
| MyPrint() { |
| count = 0; |
| } |
| void operator() (int num) { |
| count++; |
| cout << "num = " << num << endl; |
| |
| } |
| int count; |
| }; |
| |
| |
| void test02() { |
| MyPrint myPrint; |
| myPrint(1); |
| myPrint(10); |
| myPrint(10); |
| myPrint(10); |
| myPrint(10); |
| cout << "调用函数对象"<< myPrint.count << "次"<<endl; |
| } |
| |
| void doPrint(MyPrint print,int num) { |
| print(num); |
| } |
| void test03() { |
| MyPrint myPrint; |
| doPrint(myPrint,19); |
| } |
总结: 函数对象(仿函数)重载了(),所以就像函数的调用。作为类型与模板配合使用。
set<int,myCompare>
2 谓词
普通函数或返回值是bool值的函数对象(operator()),
| class Greater20 { |
| public: |
| bool operator()(int val) { |
| return val > 20; |
| } |
| }; |
| |
| |
| |
| void test01() { |
| vector<int> v; |
| v.push_back(10); |
| v.push_back(20); |
| v.push_back(30); |
| v.push_back(40); |
| v.push_back(50); |
| |
| |
| Greater20 greater20Then; |
| vector<int>::iterator pos = find_if(v.begin(),v.end(), greater20Then); |
| if (pos != v.end()) { |
| cout << "找到大于20的位置="<< *pos << endl; |
| } |
| else { |
| cout << "未找到" << endl; |
| } |
| } |
| |
| |
| class MyCompare{ |
| public: |
| bool operator()(int v1,int v2) { |
| return v1 > v2; |
| } |
| }; |
| |
| void test02() { |
| |
| vector<int> v; |
| v.push_back(10); |
| v.push_back(20); |
| v.push_back(30); |
| v.push_back(40); |
| v.push_back(50); |
| |
| sort(v.begin(),v.end(), MyCompare()); |
| |
| for_each(v.begin(), v.end(), [](int val) { |
| cout << val << " "; |
| }); |
| cout << endl; |
| } |
3 内建函数对象的使用
| #include <functional> |
| #define _CRT_SECURE_NO_WARNINGS |
| #include <iostream> |
| using namespace std; |
| #include <functional> |
| #include <vector> |
| #include <algorithm> |
| |
| void test01() { |
| |
| |
| |
| negate<int> n; |
| cout <<n(10) << endl; |
| |
| |
| |
| plus<int> p; |
| cout << p(1, 1) << endl; |
| } |
| |
| |
| void test02() { |
| |
| vector<int> v; |
| v.push_back(10); |
| v.push_back(11); |
| v.push_back(12); |
| v.push_back(9); |
| v.push_back(6); |
| |
| sort(v.begin(),v.end(),greater<int>()); |
| |
| for (int a : v) { |
| cout << a << " "; |
| } |
| } |
| |
| int main() |
| { |
| test02(); |
| system("pause"); |
| return EXIT_SUCCESS; |
| } |
4 适配器
函数适配器
// 第一步 绑定数据
// 第二步 继承类binary_function<参数类型1,参数类型2,返回值类型>
// 第三步 加const修饰 operator()
| class MyPrint : public binary_function<int,int,void> |
| { |
| public: |
| void operator() (int v,int start) const |
| { |
| cout << "v=" << v << " start=" << start << " v+start=" << v + start << endl; |
| } |
| }; |
| |
| void test01() { |
| vector<int> v; |
| for (int i = 0; i < 10;i++) { |
| v.push_back(i); |
| } |
| |
| cout << "请输入一个起始值:" << endl; |
| int num; |
| cin >> num; |
| |
| for_each(v.begin(),v.end(), bind2nd(MyPrint(),num)); |
| |
| } |
| |
| |
| class greater5 :public unary_function<int,bool> |
| { |
| public : |
| bool operator()(int v) const |
| { |
| return v > 5; |
| } |
| }; |
| |
| void test02() { |
| |
| vector<int> v; |
| for (int i = 0; i < 10;i++) { |
| v.push_back(i); |
| } |
| |
| |
| vector<int>::iterator pos = find_if(v.begin(),v.end(), not1(greater5())); |
| |
| if (pos != v.end()) { |
| cout << "找到小于5的数字" << *pos << endl; |
| } |
| } |
| |
| |
| vector<int>::iterator pos = find_if(v.begin(), v.end(), not1( bind2nd(greater<int>(),5))); |
| void myPrint(int v,int start) { |
| cout << v << " "; |
| } |
| |
| void test03() { |
| vector<int> v; |
| for (int i = 0; i < 10;i++) { |
| v.push_back(i ); |
| } |
| |
| for_each(v.begin(),v.end(),bind2nd(ptr_fun(myPrint),5)); |
| cout << "\n"; |
| } |
| |
| |
| class Person { |
| public: |
| Person(string name, int age) { |
| this->m_name = name; |
| this->m_age = age; |
| } |
| string m_name; |
| int m_age; |
| |
| }; |
| void myPrintPerson(Person &p) { |
| cout << "姓名:" << p.m_name << "\t年龄:" << p.m_age << endl; |
| } |
| |
| void test04() { |
| vector<Person> v; |
| Person p1("张三",13); |
| Person p2("李四", 23); |
| Person p3("王五", 33); |
| Person p4("赵六", 43); |
| |
| v.push_back(p1); |
| v.push_back(p2); |
| v.push_back(p3); |
| v.push_back(p4); |
| for_each(v.begin(),v.end(), myPrintPerson); |
| } |
| |
| |
| |
| for_each(v.begin(), v.end(),mem_fun_ref(&Person::showPerson)); |
5 常用遍历算法
第一个是for_each
使用for_each需要导入模块
两个作用:1.可以保存状态, 2. 可以绑定参数进行输出
| struct MyPrint { |
| void operator()(int v) { |
| cout << v << " "; |
| m_Count++; |
| } |
| int m_Count=0; |
| }; |
| void test01() { |
| vector<int> v; |
| for (int i = 0; i < 10;i++) { |
| v.push_back(i); |
| } |
| |
| MyPrint print = for_each(v.begin(), v.end(), MyPrint()); |
| cout << "累计次数="<< print.m_Count << endl; |
| cout << endl; |
| } |
| transform算法,将指定容器中的元素搬运到另外一个容器中。 |
| void test04() { |
| vector<int> v; |
| for (int i = 0; i < 10; i++) { |
| v.push_back(i); |
| } |
| vector<int> target; |
| |
| target.resize(v.size()); |
| transform(v.begin(),v.end(),target.begin(), Transform()); |
| |
| for_each(target.begin(), target.end(), [](int val) { |
| cout << val << " "; |
| }); |
| } |
| |
| class Transform2 { |
| public: |
| int operator()(int val,int val2) { |
| return val + val2; |
| } |
| }; |
| |
| void test05() { |
| vector<int> v1; |
| vector<int> v2; |
| |
| for (int i = 0; i < 10;i++) { |
| v1.push_back(i+100); |
| v2.push_back(i+10); |
| } |
| |
| vector<int> vtarget; |
| vtarget.resize(v1.size()); |
| transform(v1.begin(),v1.end(),v2.begin(),vtarget.begin(),Transform2()); |
| |
| for_each(vtarget.begin(), vtarget.end(), [](int val) { |
| cout << val << " "; |
| }); |
| cout << endl; |
| } |
6 常用的查找算法
使用find()查找SLT容器中的元素。
| void test() { |
| vector<int> v; |
| for (int i = 0; i < 10; i++) { |
| v.push_back(i); |
| } |
| vector<int>::iterator ele = find(v.begin(),v.end(),5); |
| if (ele != v.end()) { |
| cout << "找到\n"; |
| } |
| else { |
| cout << "未找到\n"; |
| } |
| } |
查找自定义的数据类型
| #define _CRT_SECURE_NO_WARNINGS |
| #include <iostream> |
| using namespace std; |
| #include <algorithm> |
| #include <vector> |
| #include <string > |
| |
| void test() { |
| vector<int> v; |
| for (int i = 0; i < 10; i++) { |
| v.push_back(i); |
| } |
| |
| vector<int>::iterator ele = find(v.begin(),v.end(),5); |
| if (ele != v.end()) { |
| cout << "找到\n"; |
| } |
| else { |
| cout << "未找到\n"; |
| } |
| } |
| |
| class Person { |
| public: |
| Person(string name, int age) { |
| this->m_Name = name; |
| this->age = age; |
| } |
| |
| bool operator==(const Person &p) { |
| if (this->m_Name == p.m_Name && this->age == p.age) { |
| return true; |
| } |
| else { |
| return false; |
| } |
| } |
| |
| string m_Name; |
| int age; |
| }; |
| |
| |
| |
| void test02() { |
| vector<Person> p; |
| |
| Person p1("Alice",12); |
| Person p2("Bob",21); |
| Person p3("Kili",23); |
| |
| p.push_back(p1); |
| p.push_back(p2); |
| p.push_back(p3); |
| |
| vector<Person>::iterator pos = find(p.begin(),p.end(),p2); |
| if (pos != p.end()) { |
| cout << pos->m_Name << " " << pos->age << endl; |
| } |
| else{ |
| cout << "没有找到" << endl; |
| } |
| } |
| int main() |
| { |
| test02(); |
| system("pause"); |
| return EXIT_SUCCESS; |
| } |
| |
| class MyCompare:public binary_function<Person *, Person *,bool> |
| { |
| public: |
| |
| bool operator()( Person * p1, Person * p2) const |
| { |
| if (p1->m_Name == p2->m_Name && p1->age == p2->age) { |
| return true; |
| } |
| else return false; |
| } |
| }; |
| |
| void test03() { |
| vector<Person *> p; |
| |
| Person p1("Alice", 12); |
| Person p2("Bob", 21); |
| Person p3("Kili", 23); |
| |
| p.push_back(&p1); |
| p.push_back(&p2); |
| p.push_back(&p3); |
| |
| vector<Person *>::iterator pos = find_if(p.begin(),p.end(), bind2nd(MyCompare(),&p1)); |
| |
| if (pos != p.end() ) { |
| cout << "找到:" <<(*pos)->m_Name<<"->"<<(*pos)->age<< endl; |
| } |
| else { |
| cout << "未找到" << endl; |
| } |
| } |
| |
| |
| |
| |
| |
| |
| |
| void test04() |
| { |
| vector<int> v; |
| v.push_back(2); |
| v.push_back(3); |
| v.push_back(4); |
| v.push_back(5); |
| v.push_back(5); |
| v.push_back(6); |
| v.push_back(7); |
| |
| vector<int>::iterator pos = adjacent_find(v.begin(), v.end()); |
| if (pos !=v.end()) { |
| cout << "找到" <<*pos << endl; |
| } |
| else { |
| cout << "找到相邻的元素" << endl; |
| } |
| } |
| |
| |
| |
| |
| void test05() |
| { |
| vector<int> v; |
| v.push_back(2); |
| v.push_back(3); |
| v.push_back(4); |
| v.push_back(5); |
| v.push_back(5); |
| v.push_back(6); |
| v.push_back(7); |
| |
| bool res = binary_search (v.begin(), v.end(),5); |
| if (res) { |
| cout << "找到" << endl; |
| } |
| else { |
| cout << "没找到" << endl; |
| } |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| class Greate4 { |
| public: |
| bool operator()(int val) { |
| return val > 4; |
| } |
| }; |
| |
| void test06() |
| { |
| vector<int> v; |
| v.push_back(2); |
| v.push_back(3); |
| v.push_back(4); |
| v.push_back(5); |
| v.push_back(5); |
| v.push_back(6); |
| v.push_back(7); |
| |
| int nums = count(v.begin(),v.end(),5); |
| cout << nums << endl; |
| int num = count_if(v.begin(),v.end(), Greate4()); |
| cout << num << endl; |
| } |
7 常用的排序算法
| #define _CRT_SECURE_NO_WARNINGS |
| #include <iostream> |
| using namespace std; |
| #include <vector> |
| #include <algorithm> |
| #include <functional> |
| #include <ctime> |
| |
| |
| |
| void test01() { |
| |
| vector<int> v1; |
| vector<int> v2; |
| |
| for (int i = 0; i < 10;i++) { |
| v1.push_back(i); |
| v2.push_back(i+ 1); |
| } |
| |
| vector<int> vTaregt; |
| vTaregt.resize(v1.size()+v2.size()); |
| merge(v1.begin(),v1.end(),v2.begin(),v2.end(),vTaregt.begin()); |
| |
| for_each(vTaregt.begin(), vTaregt.end(), [](int v) {cout << v << " "; }); |
| |
| } |
| |
| |
| |
| |
| |
| void test02() { |
| vector<int> v1; |
| |
| v1.push_back(2); |
| v1.push_back(1); |
| v1.push_back(9); |
| v1.push_back(3); |
| v1.push_back(11); |
| |
| sort(v1.begin(),v1.end()); |
| for_each(v1.begin(), v1.end(), [](int v) { cout << v << " "; }); |
| sort(v1.begin(), v1.end(),greater<int>()); |
| cout << endl; |
| for_each(v1.begin(), v1.end(), [](int v) { cout << v << " "; }); |
| } |
| |
| |
| void test03() { |
| srand( (unsigned int)time(NULL)); |
| 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(), [](int v) { cout << v << " "; }); |
| cout << endl; |
| |
| |
| reverse(v.begin(),v.end()); |
| for_each(v.begin(), v.end(), [](int v) { cout << v << " "; }); |
| cout << endl; |
| } |
| |
| int main() |
| { |
| |
| |
| test03(); |
| system("pause"); |
| return EXIT_SUCCESS; |
| } |
| |
| 合并算法(merge) / 排序算法 |
8 常用的拷贝和替换算法
| |
| void test01() { |
| vector<int> v; |
| for (int i = 0; i < 10;i++) { |
| v.push_back(i); |
| } |
| |
| vector<int> v1; |
| v1.resize(v.size()); |
| |
| copy(v.begin(),v.end(),v1.begin()); |
| for_each(v1.begin(), v1.end(), [](int v) { cout << v << " "; }); |
| cout << endl; |
| } |
| |
| |
| |
| |
| |
| void test02() { |
| vector<int> v; |
| for (int i = 0; i < 4;i++) { |
| v.push_back(i); |
| } |
| |
| replace(v.begin(),v.end(),3,300); |
| for_each(v.begin(), v.end(), [](int v) { cout << v << " "; }); |
| } |
| |
| |
| void test03() { |
| |
| vector<int> v1; |
| for (int i = 0; i < 10; i++) { |
| v1.push_back(i); |
| } |
| |
| vector<int> v2; |
| v2.push_back(10); |
| v2.push_back(20); |
| v2.push_back(30); |
| v2.push_back(40); |
| |
| cout << "交换前的数据:" << endl; |
| for_each(v1.begin(), v1.end(), [](int v) { cout << v << " "; }); |
| cout << endl; |
| |
| cout << "交换后的数据" << endl; |
| swap(v1,v2); |
| for_each(v1.begin(), v1.end(), [](int v) { cout << v << " "; }); |
| cout << endl; |
| |
| for_each(v2.begin(), v2.end(), [](int v) { cout << v << " "; }); |
| cout << endl; |
| } |
9 常用的算数生成算法
| #define _CRT_SECURE_NO_WARNINGS |
| #include <iostream> |
| using namespace std; |
| #include <vector> |
| #include <numeric> |
| #include <iterator> |
| |
| |
| void test01() { |
| vector<int> v; |
| for (int i = 0; i < 10;i++) { |
| v.push_back(i); |
| } |
| |
| |
| int res = accumulate(v.begin(),v.end(),10); |
| cout << res << endl; |
| |
| } |
| |
| |
| void test02() { |
| vector <int> v; |
| v.resize(10); |
| fill(v.begin(),v.end(),1000); |
| |
| copy(v.begin(),v.end(),ostream_iterator<int>(cout," ")); |
| |
| } |
| |
| int main() |
| { |
| test02(); |
| system("pause"); |
| return EXIT_SUCCESS; |
10 常用的集合算法(一般用不到)
| 交集、并集、差集 |
| |
| |
| |
| |
| void test01() { |
| |
| vector<int> v1; |
| vector<int> v2; |
| for (int i = 0; i < 10;i++) { |
| v1.push_back(i); |
| v2.push_back(i + 5); |
| } |
| |
| vector<int> vTarget; |
| vTarget.resize( min(v1.size(),v2.size()) ); |
| vector<int>::iterator end = set_intersection(v1.begin(),v1.end(),v2.begin(),v2.end(),vTarget.begin()); |
| |
| |
| |
| copy(vTarget.begin(), end, ostream_iterator<int>(cout," ")); |
| } |
| |
| |
| |
| void test02() { |
| vector<int> v1; |
| vector<int> v2; |
| for (int i = 0; i < 10; i++) { |
| v1.push_back(i); |
| v2.push_back(i + 5); |
| } |
| |
| vector<int> vTarget; |
| vTarget.resize(v1.size()+v2.size()); |
| vector<int>::iterator end = set_union(v1.begin(), v1.end(), v2.begin(), v2.end(), vTarget.begin()); |
| |
| |
| |
| copy(vTarget.begin(), end, ostream_iterator<int>(cout, " ")); |
| } |
| |
| |
| void test03() { |
| |
| vector<int> v1; |
| vector<int> v2; |
| for (int i = 0; i < 10; i++) { |
| v1.push_back(i); |
| v2.push_back(i + 5); |
| } |
| |
| vector<int> vTarget; |
| vTarget.resize(v1.size() + v2.size()); |
| |
| vector<int>::iterator end = set_difference(v1.begin(), v1.end(), v2.begin(), v2.end(), vTarget.begin()); |
| |
| |
| |
| copy(vTarget.begin(), end, ostream_iterator<int>(cout, " ")); |
| } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· .NET Core 中如何实现缓存的预热?
· 三行代码完成国际化适配,妙~啊~
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?