5.2 常用查找算法
学习目标:
-
掌握常用的查找算法
算法简介:
-
find //查找元素
-
find_if //按条件查找元素
-
adjacent_find //查找相邻重复元素
-
binary_search //二分查找法
-
count //统计元素个数
-
count _if //按条件同级元素
5.2.1 find
功能描述:
-
查找指定元素,找到返回指定元素的迭代器,找不到返回结束迭代器end()
函数原型:
-
find (iterator beg , iterator end ,value);
//按值查找,找到返回指定位置迭代器,找不到返回结束迭代器位置
//beg开始迭代器
//end结束迭代器
//value 查找的元素
示例:
#include <iostream> #include<string> using namespace std; #include <vector> #include<algorithm> //常用查找算法 //find //查找内置数据 void test01() { vector <int> v; for (int i = 0; i < 10; i++) { v.push_back(i); } //查找容器中 是否有5这个元素 vector<int>::iterator it = find(v.begin(), v.end(), 5); if (it == v.end()) { cout << "没有找到" << endl; } else { cout << "找到了" <<*it <<endl; } } class Person { public: Person(string name, int age) { this->m_Name = name; this->m_Age = age; } //重载== 底层find 知道如何对比person数据类型 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("aaa", 10); Person p2("bbb", 20); Person p3("ccc", 30); Person p4("ddd", 40); Person p5("eee", 50); Person p6("fff", 60); //插入数据到容器中 v.push_back(p1); v.push_back(p2); v.push_back(p3); v.push_back(p4); v.push_back(p5); v.push_back(p6); Person pp("bbb", 20); vector<Person>::iterator it = find(v.begin(),v.end(),pp); if (it == v.end()) { cout << "没有找到" << endl; } else { cout << "找到元素 姓名: " << it->m_Name << " 年龄: " << it->m_Age << endl; } } int main() { //test01(); test02(); system("pause"); return 0; }
效果图:
总结:
利用find可以在容器中找指定的元素,返回值是迭代器
5.2.2 find_of
功能描述:
-
按条件查找元素
函数原型:
-
find_if(iterator beg,iterator end,_Pred);
//按值查找元素,找到返回指定位置迭代器,找不到返回结束迭代器位置
//beg 开始迭代器
//end结束迭代器
//_Pred 函数或者谓词(返回bool类型的仿函数)
示例:
#include <iostream> using namespace std; //容器头文件 #include<vector> #include<algorithm> #include<string> //常用查找算法 find_if //1、查找内置数据类型 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 it = find_if(v.begin(), v.end(), GreaterFive()); //判断结果有无找到:是否为结束迭代器 if (it==v.end()) { cout << "未找到" << endl; } else { cout << "找到了" << *it << endl; } } //2、查找自定义数据类型 class Person { public: Person(string name, int age) { this->m_Age = age; this->m_Name = name; } string m_Name; int m_Age; }; class AgeGreater20 { public: bool operator()( Person &p) { return p.m_Age > 20; } }; void test02() { //创建容器 vector<Person> v; //创建数据 Person p1("aa", 10); Person p2("bb", 20); Person p3("cc", 30); Person p4("dd", 40); Person p5("ee", 50); //尾插法插入数据 v.push_back(p1); v.push_back(p2); v.push_back(p3); v.push_back(p4); v.push_back(p5); //找一个年龄大于20的人 find_if vector<Person>::iterator it = find_if(v.begin(), v.end(), AgeGreater20()); //判断 if (it == v.end()) { cout << "没有找到" << endl; } else { cout << "找到姓名 "<< it->m_Name<<" 年龄 : "<<(*it).m_Age<< endl; } } int main() { //找大于5的数 cout << "找大于5的数" << endl; test01(); //找年龄大于20的人 cout << "找年龄大于20的" << endl; test02(); system("pause"); return 0; }
效果图:
5.2.3 adjacent_find
功能描述:
-
查找相邻重复元素
函数原型:
-
adjacent_find(iterator beg,iterator end);
//查找相邻重复元素,返回相邻元素的第一个位置的迭代器
//beg 开始迭代器
//end 结束迭代器
示例:
#include <iostream> using namespace std; //容器头文件 #include<vector> #include<algorithm> //常用查找算法 adjacent_find // void test01() { //创建容器 vector<int>v; //插入数据 v.push_back(0); v.push_back(9); v.push_back(6); v.push_back(5); v.push_back(6); v.push_back(0); v.push_back(3); v.push_back(3); v.push_back(2); v.push_back(4); v.push_back(6); v.push_back(7); v.push_back(1); //查找相邻元素 用迭代器接收返回数据 vector<int>::iterator pos = adjacent_find(v.begin(), v.end()); //判断 if (pos==v.end()) { cout << "未找到" << endl; } else { cout << "找到了相邻重复元素:" << *pos << endl; } } int main() { //调用测试test01() test01(); system("pause"); return 0; }
效果图:
总结: 面试题中如果出现相邻重复元素,记得用STL中的adjacent_find算法
5.2.4 binary_search
功能描述:
-
查找指定元素是否存在
函数原型:
-
bool binary_search(iterator beg, iterator end , value);
//查找指定的元素,查找返回true 否则false
//注意,在无序序列中不可用
//beg 开始迭代器
//end 结束迭代器
示例:
#include <iostream> using namespace std; //容器头文件 #include<vector> #include<algorithm> //常用查找算法 binary _search 二分查找 void test01() { //创建容器 vector<int> v; //插入数据 for (int i=0;i<10;i++) { v.push_back(i); } //如果是无序序列,结果未知! //查找元素中是否有 9 元素//返回的是bool类型 bool ret=binary_search(v.begin(), v.end(), 9); //注意:容器必须是有序的序列 //判断ret if (ret) { cout << "找到了" << endl; } else { cout << "未找到" << endl; } } int main() { //调用测试test01() test01(); system("pause"); return 0; }
效果图:
总结:
二分查找法查找效率很高,值得注意的是查找的容器中元素必须是有序序列
5.2.5 count
功能描述:
-
统计元素个数
函数原型:
-
count(iterator beg,iterator end, value);
//统计元素出现次数
//beg开始迭代器
//end结束迭代器
//value 统计的元素
示例:
#include <iostream> using namespace std; #include<string> //容器头文件 #include <vector> //算法头文件 #include <algorithm> //常用查找算法 _count //1、统计内置数据类型 void test01() { //创建容器 vector<int> v; //插入数据 v.push_back(10); v.push_back(20); v.push_back(30); v.push_back(10); v.push_back(20); v.push_back(50); v.push_back(60); v.push_back(20); v.push_back(10); //统计个数 int num = count(v.begin(), v.end(), 10); //输出个数 cout << "容器里10的个数为" << num << endl; } //查找自定义数据类型 //人类 年龄 姓名 class Person { public: Person(string name, int age) { this->m_Age = age; this->m_Name = name; } bool operator ==(const Person &p) { if (this->m_Age==p.m_Age) { return true; } else { return false; } } string m_Name; int m_Age; }; void test02() { //创建容器 vector<Person> v; //创建数据 Person p1("刘备",25 ); Person p2("张飞",25 ); Person p3("关羽", 25); Person p4("赵云", 30); Person p5("貂蝉", 18); Person p6("诸葛亮",25); //插入数据 三国 v.push_back(p1); v.push_back(p2); v.push_back(p3); v.push_back(p4); v.push_back(p5); //统计与诸葛亮同岁的人个数 int num=count( v.begin(), v.end(), p6); //输出个数 cout << "与诸葛亮年龄相同的人的个数为:" << num << endl; } int main() { //调用测试test01() test01(); 调用测试test02() test02(); system("pause"); return 0; }
效果图:
总结:
统计自定义数据类型时候,需要配合重载 operator ==
5.2.6 count_if
功能描述:
-
按条件统计元素个数
函数原型
-
count_if(iterator beg,iterator end,_Pred);
//按条件统计元素出现次数
//beg开始迭代器
//end结束迭代器
//_Pred 谓词
示例:
#include <iostream> using namespace std; #include<string> //容器头文件 #include <vector> //算法头文件 #include <algorithm> //常用的查找算法 count_if //统计内置数据类型 //谓词 仿函数 class Greater20 { public: bool operator ()(int val) { if( val > 20) { return true; } else { return false; } } }; void test01() { //创建vector容器 int vector<int> v; //插入数据 v.push_back(10); v.push_back(20); v.push_back(30); v.push_back(20); v.push_back(30); v.push_back(50); //统计大于20的个数 int num=count_if(v.begin(), v.end(), Greater20()); //输出 cout << "大于20的个数为" << num << endl; } //统计自定义数据类型 //人类 姓名 年龄 class Person { public: Person(string name, int age) { this->m_Age = age; this->m_Name = name; } string m_Name; int m_Age; }; //仿函数 class AgeGreater20 { public: bool operator()(const Person &p) { return p.m_Age > 20; } }; void test02() { //创建容器 vector<Person> v; //创建数据 三国 Person p1("刘备", 30); Person p2("张飞", 30); Person p3("关羽", 20); Person p4("曹操", 30); Person p5("赵云", 25); Person p6("貂蝉", 20); //向容器插入数据 v.push_back(p1); v.push_back(p2); v.push_back(p3); v.push_back(p4); v.push_back(p5); v.push_back(p6); //统计 大于20岁人员个数 int num = count_if(v.begin(), v.end(), AgeGreater20()); //输出 个数 cout << "年龄大于20岁的个数" << num << endl; } int main() { //调用测试test01() test01(); 调用测试test02() test02(); system("pause"); return 0; }
效果图: