当前位置:   article > 正文

C++基础-STL基础-常用算法

C++基础-STL基础-常用算法

//STL的常用算法
//算法主要是由<algorithm> <functional><numeric>组成
//<algorithm> STL头文件中最大的一个 范围涉及到 比较,交换,查找,遍历,复制,修改等
//<numeric>体积很小 只包括几个在序列上面进行简单教学运算的模板函数
//<functional>定义了一些模板类,用以声明函数对象

1//常用遍历算法

//for_each 遍历容器

  1. //普通函数
  2. void print01(int val)
  3. {
  4. cout << val <<" ";
  5. }
  6. //仿函数
  7. class myprint02
  8. {
  9. public:
  10. void operator()(int val)
  11. {
  12. cout << val << " ";
  13. }
  14. };
  15. void test01()
  16. {
  17. vector<int> v;
  18. for(int i = 0; i <10; i++)
  19. {
  20. v.push_back(i);
  21. }
  22. //普通函数,放一个函数名
  23. for_each(v.begin(),v.end(),print01);
  24. cout << endl;
  25. //仿函数,必须传一个函数对象,所以要传一个匿名的函数对象
  26. for_each(v.begin(),v.end(),myprint02());
  27. cout << endl;
  28. }
  29. int main()
  30. {
  31. //创建随机因子;
  32. srand((unsigned)time(NULL));
  33. test01();
  34. pause();
  35. return 0;
  36. }

2 transform算法

  1. //常用遍历算法
  2. //transform
  3. //注意 目标容器需要提前开辟空间
  4. //仿函数
  5. //写这个仿函数,可以让transform的过程中可以做一些操作
  6. class TransForm
  7. {
  8. public:
  9. int operator()(int val)
  10. {
  11. return val+100;
  12. }
  13. };
  14. class myprint
  15. {
  16. public:
  17. void operator()(int val)
  18. {
  19. cout << val << " ";
  20. }
  21. };
  22. void test01()
  23. {
  24. vector<int> v;
  25. for(int i = 0; i <10; i++)
  26. {
  27. v.push_back(i);
  28. }
  29. vector<int> vtarget;
  30. vtarget.resize(v.size());
  31. transform(v.begin(),v.end(),vtarget.begin(),TransForm());
  32. for_each(vtarget.begin(),vtarget.end(),myprint());
  33. cout << endl;
  34. }

2 常用查找算法

//find     //查找元素  返回迭代器
//find_if    //按条件查找  返回迭代器
//adjacent_find    //查找相邻重复元素
//binary_search //二分查找法
//count    //统计元素个数
//count_if //按条件统计

1 find

  1. //STL常用算法
  2. //查找算法
  3. //1.find
  4. // 查找内置数据类型
  5. void test01()
  6. {
  7. vector<int> v;
  8. for(int i = 0; i< 10;i++)
  9. {
  10. v.push_back(i);
  11. }
  12. vector<int>::iterator pos = find(v.begin(),v.end(),5);
  13. if(pos == v.end())
  14. {
  15. cout << "None" << endl;
  16. }
  17. else
  18. {
  19. cout << "find"<<endl;
  20. }
  21. }
  22. //查找自定义数据
  23. //必须重载==号
  24. class person
  25. {
  26. public:
  27. person(string name ,int age)
  28. {
  29. this->m_name = name;
  30. this->m_age = age;
  31. }
  32. bool operator==(const person &p)
  33. {
  34. if( this->m_name == p.m_name
  35. && this->m_age == p.m_age)
  36. {
  37. return true;
  38. }
  39. else
  40. {
  41. return false;
  42. }
  43. }
  44. string m_name;
  45. int m_age;
  46. };
  47. void test02()
  48. {
  49. vector<person> v;
  50. person p1("aa",10);
  51. person p2("bb",20);
  52. person p3("cc",30);
  53. person p4("dd",40);
  54. v.push_back(p1);
  55. v.push_back(p2);
  56. v.push_back(p3);
  57. v.push_back(p4);
  58. person pp("bb",20);
  59. //需要重载==号
  60. vector<person>::iterator it = find(v.begin(),v.end(),pp);
  61. if(it != v.end())
  62. {
  63. cout << "find " << it->m_age << it->m_name << endl;
  64. }
  65. else
  66. {
  67. cout << "None" << endl;
  68. }
  69. }

2 find_if

  1. //2.find_if
  2. class greaterfive
  3. {
  4. public:
  5. bool operator()(int val)
  6. {
  7. return val > 5;
  8. }
  9. };
  10. //内置数据类型
  11. void test01()
  12. {
  13. vector<int> v;
  14. for(int i = 0 ;i < 10 ; i++)
  15. {
  16. v.push_back(i);
  17. }
  18. vector<int>::iterator pos = find_if(v.begin(),v.end(),greaterfive());
  19. if(pos == v.end())
  20. {
  21. cout << "None" << endl;
  22. }
  23. else
  24. {
  25. cout << "find: "<< *pos << endl;
  26. }
  27. pos++;
  28. cout << *pos << endl;
  29. }
  30. //自定义数据类型
  31. class person
  32. {
  33. public:
  34. person(string name,int age)
  35. {
  36. this->m_name = name;
  37. this->m_age = age;
  38. }
  39. string m_name;
  40. int m_age;
  41. };
  42. class greater20
  43. {
  44. public:
  45. bool operator()(const person &p)
  46. {
  47. return p.m_age > 20;
  48. }
  49. };
  50. void test02()
  51. {
  52. vector<person> v;
  53. person p1("a",10);
  54. person p2("b",20);
  55. person p3("c",30);
  56. person p4("d",40);
  57. v.push_back(p1);
  58. v.push_back(p2);
  59. v.push_back(p3);
  60. v.push_back(p4);
  61. vector<person>::iterator it = find_if(v.begin(),v.end(),greater20());
  62. if(it == v.end())
  63. {
  64. cout << "none"<<endl;
  65. }
  66. else
  67. {
  68. cout << it->m_name << it->m_age<<endl;;
  69. }
  70. }

3 adjacent_find

  1. //查找算法
  2. //3.adjecent_find
  3. //查找重复相邻
  4. //内置数据类型
  5. void test01()
  6. {
  7. vector<int> v;
  8. v.push_back(0);
  9. v.push_back(2);
  10. v.push_back(0);
  11. v.push_back(3);
  12. v.push_back(1);
  13. v.push_back(4);
  14. v.push_back(3);
  15. v.push_back(3);
  16. vector<int>::iterator pos = adjacent_find(v.begin(),v.end());
  17. if(pos == v.end())
  18. {
  19. cout << "None" << endl;
  20. }
  21. else
  22. {
  23. cout << "find: "<< *pos << endl;
  24. }
  25. }
  26. //自定义数据类型
  27. class person
  28. {
  29. public:
  30. person(string name,int age)
  31. {
  32. this->m_name = name;
  33. this->m_age = age;
  34. }
  35. bool operator==(const person &p)
  36. {
  37. if(this->m_name == p.m_name
  38. && this->m_age == p.m_age)
  39. {
  40. return true;
  41. }
  42. else
  43. {
  44. return false;
  45. }
  46. }
  47. string m_name;
  48. int m_age;
  49. };
  50. void test02()
  51. {
  52. vector<person> v;
  53. person p1("a",10);
  54. person p2("b",20);
  55. person p3("b",20);
  56. person p4("d",40);
  57. v.push_back(p1);
  58. v.push_back(p2);
  59. v.push_back(p3);
  60. v.push_back(p4);
  61. vector<person>::iterator it = adjacent_find(v.begin(),v.end());
  62. if(it == v.end())
  63. {
  64. cout << "none"<<endl;
  65. }
  66. else
  67. {
  68. cout << it->m_name << it->m_age<<endl;;
  69. }
  70. }

4 binary_search

自定义数据是我自己写的,似乎自定义数据无法判断顺序是否有序,所以不适合用binary_search查找

  1. //3.binary_search
  2. //二叉树查找
  3. //内置数据类型
  4. void test01()
  5. {
  6. vector<int> v;
  7. for(int i = 0;i<10;i++)
  8. {
  9. v.push_back(i);
  10. }
  11. //必须查找有序序列
  12. //如果是无序序列,结果未知
  13. bool ret = binary_search(v.begin(),v.end(),9);
  14. if(ret == true)
  15. {
  16. cout << "find" << endl;
  17. }
  18. else
  19. {
  20. cout << "None" << endl;
  21. }
  22. }
  23. //自定义数据类型
  24. class person
  25. {
  26. public:
  27. person(string name,int age)
  28. {
  29. this->m_name = name;
  30. this->m_age = age;
  31. }
  32. string m_name;
  33. int m_age;
  34. };
  35. bool operator<(const person &p1,const person &p2)
  36. {
  37. if(p1.m_name < p2.m_name
  38. && p1.m_age < p2.m_age)
  39. {
  40. return true;
  41. }
  42. else
  43. {
  44. return false;
  45. }
  46. }
  47. void test02()
  48. {
  49. vector<person> v;
  50. person p1("a",10);
  51. person p2("b",20);
  52. person p3("c",30);
  53. person p4("d",40);
  54. v.push_back(p1);
  55. v.push_back(p2);
  56. v.push_back(p3);
  57. v.push_back(p4);
  58. person pp("c",30);
  59. bool ret = binary_search(v.begin(),v.end(),pp);
  60. if(ret == false)
  61. {
  62. cout << "none"<<endl;
  63. }
  64. else
  65. {
  66. cout << "find"<<endl;;
  67. }
  68. }

5 统计

我有一个疑问:为什么binary_search的 operator< 就要作为全局函数,而operator==就可以全局也可以,类成员也可以?这是为什么?

  1. //STL常用算法
  2. //查找算法
  3. //3.count
  4. //统计
  5. //内置数据类型
  6. void test01()
  7. {
  8. vector<int> v;
  9. for(int i = 0;i<10;i++)
  10. {
  11. v.push_back(2);
  12. }
  13. int num = count(v.begin(),v.end(),2);
  14. {
  15. cout << num << endl;
  16. }
  17. }
  18. //自定义数据类型
  19. class person
  20. {
  21. public:
  22. person(string name,int age)
  23. {
  24. this->m_name = name;
  25. this->m_age = age;
  26. }
  27. bool operator==(const person &p2)
  28. {
  29. if(this->m_name == p2.m_name
  30. && this->m_age == p2.m_age)
  31. {
  32. return true;
  33. }
  34. else
  35. {
  36. return false;
  37. }
  38. }
  39. string m_name;
  40. int m_age;
  41. };
  42. // bool operator==(const person &p1,const person &p2)
  43. // {
  44. // if(p1.m_name == p2.m_name
  45. // && p1.m_age == p2.m_age)
  46. // {
  47. // return true;
  48. // }
  49. // else
  50. // {
  51. // return false;
  52. // }
  53. // }
  54. void test02()
  55. {
  56. vector<person> v;
  57. person p1("a",10);
  58. person p2("c",30);
  59. person p3("c",30);
  60. person p4("d",40);
  61. v.push_back(p1);
  62. v.push_back(p2);
  63. v.push_back(p3);
  64. v.push_back(p4);
  65. person pp("c",30);
  66. int num = count(v.begin(),v.end(),pp);
  67. cout << num <<endl;
  68. }

6 有条件统计count_if

  1. //查找算法
  2. //3.count_if
  3. //统计
  4. class greater2
  5. {
  6. public:
  7. bool operator()(int val)
  8. {
  9. return val > 2;
  10. }
  11. };
  12. //内置数据类型
  13. void test01()
  14. {
  15. vector<int> v;
  16. for(int i = 0;i<10;i++)
  17. {
  18. v.push_back(i);
  19. }
  20. int num = count_if(v.begin(),v.end(),greater2());
  21. {
  22. cout << num << endl;
  23. }
  24. }
  25. //自定义数据类型
  26. class person
  27. {
  28. public:
  29. person(string name,int age)
  30. {
  31. this->m_name = name;
  32. this->m_age = age;
  33. }
  34. string m_name;
  35. int m_age;
  36. };
  37. class greater10
  38. {
  39. public:
  40. bool operator()(const person &p)
  41. {
  42. return p.m_age > 10;
  43. }
  44. };
  45. void test02()
  46. {
  47. vector<person> v;
  48. person p1("a",10);
  49. person p2("b",20);
  50. person p3("c",30);
  51. person p4("d",40);
  52. v.push_back(p1);
  53. v.push_back(p2);
  54. v.push_back(p3);
  55. v.push_back(p4);
  56. int num = count_if(v.begin(),v.end(),greater10());
  57. cout << num <<endl;
  58. }

3.常用排序算法

1 sort

  1. //STL常用算法
  2. //排序算法
  3. //sort //对容器内元素进行排序
  4. //random_shuffle //洗牌
  5. void myprint(int val)
  6. {
  7. cout << val << " ";
  8. }
  9. //内置数据类型
  10. void test01()
  11. {
  12. vector<int> v;
  13. v.push_back(10);
  14. v.push_back(30);
  15. v.push_back(20);
  16. v.push_back(40);
  17. v.push_back(50);
  18. //利用sort进行排序
  19. //升序
  20. sort(v.begin(),v.end());
  21. for_each(v.begin(),v.end(),myprint);
  22. cout << endl;
  23. //降序
  24. sort(v.begin(),v.end(),greater<int>());
  25. for_each(v.begin(),v.end(),myprint);
  26. cout << endl;
  27. }

2 random_shuffle

  1. //STL常用算法
  2. //排序算法
  3. //sort //对容器内元素进行排序
  4. //random_shuffle //洗牌
  5. void myprint(int val)
  6. {
  7. cout << val << " ";
  8. }
  9. //内置数据类型
  10. void test01()
  11. {
  12. vector<int> v;
  13. for(int i=0;i<10;i++)
  14. {
  15. v.push_back(i);
  16. }
  17. //利用random_shuffle进行洗牌
  18. //为了打乱的更随机,需要添加随机因子
  19. random_shuffle(v.begin(),v.end());
  20. for_each(v.begin(),v.end(),myprint);
  21. cout << endl;
  22. }

3 merge

两个有序容器合并,并存储到另一个容器中,也是有序的,另外源容器的有序需要是同一序列

目标容器需要提前分配空间

  1. void myprint(int val)
  2. {
  3. cout << val << " ";
  4. }
  5. //内置数据类型
  6. void test01()
  7. {
  8. vector<int> v1;
  9. for(int i=0;i<9;i++)
  10. {
  11. v1.push_back(i);
  12. }
  13. vector<int> v2;
  14. for(int i=1;i<10;i++)
  15. {
  16. v2.push_back(i);
  17. }
  18. //vtrage 目标容器需要提前分配空间
  19. vector<int> vtarge;
  20. vtarge.resize(v1.size()+v2.size());
  21. merge(v1.begin(),v1.end(),v2.begin(),v2.end(),vtarge.begin());
  22. for_each(vtarge.begin(),vtarge.end(),myprint);
  23. cout << endl;
  24. }

4 reverse

  1. void myprint(int val)
  2. {
  3. cout << val << " ";
  4. }
  5. //内置数据类型
  6. void test01()
  7. {
  8. vector<int> v1;
  9. for(int i=0;i<9;i++)
  10. {
  11. v1.push_back(i);
  12. }
  13. reverse(v1.begin(),v1.end());
  14. for_each(v1.begin(),v1.end(),myprint);
  15. cout << endl;
  16. }
  17. //自定义数据?
  18. class person
  19. {
  20. public:
  21. person(string name,int age)
  22. {
  23. this->m_name = name;
  24. this->m_age = age;
  25. }
  26. string m_name;
  27. int m_age;
  28. };
  29. void printperson(const person &p)
  30. {
  31. cout << p.m_name << " " << p.m_age << " ";
  32. }
  33. void test02()
  34. {
  35. vector<person> vp;
  36. person p1("a",10);
  37. person p2("b",11);
  38. person p3("c",12);
  39. person p4("d",13);
  40. vp.push_back(p1);
  41. vp.push_back(p2);
  42. vp.push_back(p3);
  43. vp.push_back(p4);
  44. reverse(vp.begin(),vp.end());
  45. for_each(vp.begin(),vp.end(),printperson);
  46. cout << endl;
  47. }

4 常用拷贝和替换算法

1 copy

  1. //拷贝和替换
  2. void myprint(int val)
  3. {
  4. cout << val << " ";
  5. }
  6. //内置数据类型
  7. void test01()
  8. {
  9. vector<int> v1;
  10. for(int i=0;i<9;i++)
  11. {
  12. v1.push_back(i);
  13. }
  14. vector<int> v2;
  15. v2.resize(v1.size());
  16. copy(v1.begin(),v1.end(),v2.begin());
  17. for_each(v2.begin(),v2.end(),myprint);
  18. cout << endl;
  19. }

2 替换

在一个区间的满足条件的值都会替换

  1. //仿函数
  2. class Myprint
  3. {
  4. public:
  5. void operator()(int val)
  6. {
  7. cout << val << " ";
  8. }
  9. };
  10. //内置数据类型
  11. void test01()
  12. {
  13. vector<int> v1;
  14. for(int i=0;i<9;i++)
  15. {
  16. v1.push_back(i%2);
  17. }
  18. replace(v1.begin(),v1.end(),0,200);
  19. for_each(v1.begin(),v1.end(),Myprint());
  20. cout << endl;
  21. }

3.按条件替换

  1. class greater5
  2. {
  3. public:
  4. bool operator()(int val)
  5. {
  6. return val > 5;
  7. }
  8. };
  9. //内置数据类型
  10. void test01()
  11. {
  12. vector<int> v1;
  13. for(int i=0;i<9;i++)
  14. {
  15. v1.push_back(i);
  16. }
  17. replace_if(v1.begin(),v1.end(),greater5(),200);
  18. for_each(v1.begin(),v1.end(),Myprint());
  19. cout << endl;
  20. }

我自己的写的自定义数据

  1. //自定义数据?
  2. class person
  3. {
  4. public:
  5. person(string name,int age)
  6. {
  7. this->m_name = name;
  8. this->m_age = age;
  9. }
  10. void operator=(const person& p)
  11. {
  12. this->m_age = p.m_age;
  13. this->m_name = p.m_name;
  14. }
  15. string m_name;
  16. int m_age;
  17. };
  18. class greater11
  19. {
  20. public:
  21. bool operator()(const person&p)
  22. {
  23. return p.m_age > 11;
  24. }
  25. };
  26. void printperson(const person &p)
  27. {
  28. cout << p.m_name << " " << p.m_age << " ";
  29. }
  30. void test02()
  31. {
  32. vector<person> vp;
  33. person p1("a",10);
  34. person p2("b",11);
  35. person p3("c",12);
  36. person p4("d",13);
  37. vp.push_back(p1);
  38. vp.push_back(p2);
  39. vp.push_back(p3);
  40. vp.push_back(p4);
  41. person pp("a",100);
  42. replace_if(vp.begin(),vp.end(),greater11(),pp);
  43. for_each(vp.begin(),vp.end(),printperson);
  44. cout << endl;
  45. }

4 SWAP

swap的两个容器必须是相同类型

  1. //仿函数
  2. class Myprint
  3. {
  4. public:
  5. void operator()(int val)
  6. {
  7. cout << val << " ";
  8. }
  9. };
  10. class greater5
  11. {
  12. public:
  13. bool operator()(int val)
  14. {
  15. return val > 5;
  16. }
  17. };
  18. //内置数据类型
  19. void test01()
  20. {
  21. vector<int> v1;
  22. for(int i=0;i<9;i++)
  23. {
  24. v1.push_back(i);
  25. }
  26. vector<int> v2;
  27. for(int i=100;i<109;i++)
  28. {
  29. v2.push_back(i);
  30. }
  31. swap(v1,v2);
  32. for_each(v1.begin(),v1.end(),Myprint());
  33. cout << endl;
  34. }

5 常用算数生成算法

1 accumulate

需要包含头文件<numeric>

  1. //内置数据类型
  2. void test01()
  3. {
  4. vector<int> v1;
  5. for(int i=0;i<9;i++)
  6. {
  7. v1.push_back(i);
  8. }
  9. int sum = accumulate(v1.begin(),v1.end(),0);//0 起始累加值
  10. cout << sum << endl;
  11. }

2 fill填充

后期填充

  1. //内置数据类型
  2. void test01()
  3. {
  4. vector<int> v1;
  5. v1.resize(10);
  6. //重新填充操作
  7. fill(v1.begin(),v1.end(),100);
  8. // for(int i=0;i<9;i++)
  9. // {
  10. // v1.push_back(i);
  11. // }
  12. for_each(v1.begin(),v1.end(),myprint);
  13. }

6 常用集合算法

两个源容器必须是有序序列

返回值都是目标容器的集合尾端迭代器

1.set_intersection

目标容器的大小 极端值的情况下就是 一个大容器包含一个小容器,所以取值取小容器的SIZE

set_intersection的返回值是交际中最后一个元素的位置

  1. //内置数据类型
  2. void test01()
  3. {
  4. vector<int> v1;
  5. for(int i=0;i<9;i++)
  6. {
  7. v1.push_back(i);
  8. }
  9. vector<int> v2;
  10. for(int i=5;i<14;i++)
  11. {
  12. v2.push_back(i);
  13. }
  14. vector<int> v3;
  15. //最特殊的情况,就是 大容器包含小容器,取空间取小容器
  16. v3.resize(max(v1.size(),v2.size()));
  17. vector<int>::iterator itEnd = set_intersection(v1.begin(),v1.end(),v2.begin(),v2.end(),v3.begin());
  18. cout << *itEnd << endl;
  19. for_each(v3.begin(),itEnd,myprint);
  20. }

2 set_union

  1. //内置数据类型
  2. void test01()
  3. {
  4. vector<int> v1;
  5. for(int i=0;i<9;i++)
  6. {
  7. v1.push_back(i);
  8. }
  9. vector<int> v2;
  10. for(int i=5;i<14;i++)
  11. {
  12. v2.push_back(i);
  13. }
  14. vector<int> v3;
  15. v3.resize(v1.size()+v2.size());
  16. vector<int>::iterator itEnd = set_union(v1.begin(),v1.end(),v2.begin(),v2.end(),v3.begin());
  17. cout << *itEnd << endl;
  18. for_each(v3.begin(),itEnd,myprint);
  19. }

3 set_difference

  1. //仿函数
  2. class Myprint
  3. {
  4. public:
  5. void operator()(int val)
  6. {
  7. cout << val << " ";
  8. }
  9. };
  10. //内置数据类型
  11. void test01()
  12. {
  13. vector<int> v1;
  14. for(int i=0;i<9;i++)
  15. {
  16. v1.push_back(i);
  17. }
  18. cout << "--v1--"<<endl;
  19. for_each(v1.begin(),v1.end(),myprint);
  20. cout << endl;
  21. vector<int> v2;
  22. for(int i=5;i<14;i++)
  23. {
  24. v2.push_back(i);
  25. }
  26. cout << "--v2--"<<endl;
  27. for_each(v2.begin(),v2.end(),myprint);
  28. cout << endl;
  29. cout << "---v1 VS v2 difference----"<< endl;
  30. vector<int> v3;
  31. v3.resize(v1.size());
  32. vector<int>::iterator itEnd = set_difference(v1.begin(),v1.end(),v2.begin(),v2.end(),v3.begin());
  33. for_each(v3.begin(),itEnd,myprint);
  34. cout << endl;
  35. cout << "---v2 VS v1 difference----"<< endl;
  36. vector<int> v4;
  37. v4.resize(v2.size());
  38. vector<int>::iterator itEnd2 = set_difference(v2.begin(),v2.end(),v1.begin(),v1.end(),v4.begin());
  39. for_each(v4.begin(),itEnd2,myprint);
  40. cout << endl;
  41. }

输出:

  1. --v1--
  2. 0 1 2 3 4 5 6 7 8
  3. --v2--
  4. 5 6 7 8 9 10 11 12 13
  5. ---v1 VS v2 difference----
  6. 0 1 2 3 4
  7. ---v2 VS v1 difference----
  8. 9 10 11 12 13

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/黑客灵魂/article/detail/920101
推荐阅读
相关标签
  

闽ICP备14008679号