本篇来介绍C++中find和find_if函数的使用,通过多个实例来演示。
find用于基础的查找功能,find_if可以实现更复杂的匹配查找条件。
1 find
1.1 函数原型
template <class InputIterator, class T>
InputIterator find ( InputIterator first,
InputIterator last,
constT& value );
1.2 在vector中查找
find通常用于在vector中查找是否存在指定的元素。
//g++ test1.cpp -std=c++11 -o test1
#include <unistd.h>
#include <stdio.h>
#include <vector>
#include <algorithm>
int main()
{
printf("hellon");
std::vector<int> numberList = {1, 3, 5, 7, 8, 9};
int num = 7;
// 循环查找
for (int &it : numberList)
{
if (it == num)
{
printf("find num:%d in numberListn", it);
break;
}
}
// find方式查找
auto it = std::find(numberList.begin(),numberList.end(),num);
if (it != numberList.end())
{
printf("find num:%d in numberListn", *it);
}
return0;
}
运行结果:
1.3 查找字符串
find也可用于在字符串查找字符和子串。
//g++ test2.cpp -std=c++11 -o test2
#include <unistd.h>
#include <stdio.h>
#include <string>
#include <algorithm>
int main()
{
printf("hellon");
std::string s1 = "hello world, hello c++";
auto r1 = s1.find('l');
auto r2 = s1.find('a');
auto r3 = s1.find("ll");
auto r4 = s1.find("abc");
if (r1 != std::string::npos)
{
printf("r1: 字符 'l' 首次出现的位置是 %zun", r1);
}
else
{
printf("r1: 未找到字符 'l'n");
}
if (r2 != std::string::npos)
{
printf("r2: 字符 'a' 首次出现的位置是 %zun", r2);
}
else
{
printf("r2: 未找到字符 'a'n");
}
if (r3 != std::string::npos)
{
printf("r3: 子字符串 "ll" 首次出现的位置是 %zun", r3);
}
else
{
printf("r3: 未找到子字符串 "ll"n");
}
if (r4 != std::string::npos)
{
printf("r4: 子字符串 "abc" 首次出现的位置是 %zun", r4);
}
else
{
printf("r4: 未找到子字符串 "abc"n");
}
return0;
}
运行结果:
2 find_if
在指定的范围内查找首个满足特定条件的元素
2.1 函数原型
template< class InputIt, class UnaryPredicate >
InputIt find_if( InputIt first, InputIt last, UnaryPredicate p );
2.1.1 参数
first
-
- 和
last
-
- :这两个参数确定了要搜索的元素范围,范围是
[first, last)
-
- ,也就意味着包含
first
-
- 但不包含
last
-
- 。
p
-
- :这是一个一元谓词,也就是一个可调用对象(像函数、函数对象或者 Lambda 表达式),它接收一个参数,并且返回一个可以转换为
bool
-
- 类型的值。当这个谓词对某个元素返回
true
- 时,就表明找到了符合条件的元素。
UnaryPredicate
在 C++ 标准库中,UnaryPredicate是一个用于描述一元谓词(Unary Predicate)的概念。一元谓词是一种可调用对象(比如函数、函数对象或者 Lambda 表达式),它接收一个参数,并且返回一个布尔值(通常是
bool
类型),以此来表示某种条件是否成立。在标准库的很多算法里都会用到一元谓词,像 std::find_if、std::remove_if、std::all_of、std::any_of 等。这些算法借助一元谓词来对容器中的元素进行筛选或者判断。
2.1.2 返回值
-
- 若找到了满足条件的元素,就返回指向该元素的迭代器。若未找到,就返回
last
- 。
2.2 示例一:查找vector数字元素中的第一个偶数
这里通过3种方式进行对比:
- 通过for循环的方式逐个比较通过find_if方式查找,并配合lambda表达式通过find_if方式查找,并配合匹配函数
//g++ test1.cpp -std=c++11 -o test1
#include <unistd.h>
#include <stdio.h>
#include <vector>
#include <algorithm>
bool isEven(int num)
{
return num % 2 == 0;
}
int main()
{
printf("hellon");
std::vector<int> numberList = {1, 3, 5, 7, 8, 9};
// 循环查找
for (int &it : numberList)
{
if (isEven(it))
{
printf("find even:%dn", it);
break;
}
}
// find_if方式查找(配合lambda表达式)
auto it = std::find_if(numberList.begin(),numberList.end(),
[](int num){return num % 2 == 0;});
if (it != numberList.end())
{
printf("find even:%dn", *it);
}
// find_if方式查找(配合匹配函数)
it = std::find_if(numberList.begin(),numberList.end(),isEven);
if (it != numberList.end())
{
printf("find even:%dn", *it);
}
return0;
}
运行结果:
2.3 示例二:查找vector自定义结构体中的指定成员
仍是通过3种方式进行对比:
- 通过for循环的方式逐个比较通过find_if方式查找,并配合lambda表达式(注意这里传递了1个参数)通过find_if方式查找,并配合匹配函数
//g++ test2.cpp -std=c++11 -o test2
#include <unistd.h>
#include <stdio.h>
#include <string>
#include <vector>
#include <algorithm>
struct Student
{
std::string id;
std::string name;
};
// 用于 std::find_if 的匹配函数
bool matchStudent(const Student& student, const std::string& studentID)
{
return student.id == studentID;
}
// 用于 std::find_if 的包装函数
struct MatchStudentWrapper
{
conststd::string& targetID;
MatchStudentWrapper(conststd::string& id) : targetID(id) {}
bool operator()(const Student& student) const
{
return matchStudent(student, targetID);
}
};
int main()
{
printf("hellon");
std::vector<Student> studentList = {
{"S05001", "LiMing"},
{"S05002", "ZhangHua"},
{"S05003", "WangQiang"},
{"S05005", "ZhaoLe"},
};
std::string studentID = "S05003";
// 循环查找
for (Student &it : studentList)
{
if (it.id == studentID)
{
printf("find studentID:%s name:%sn", it.id.c_str(), it.name.c_str());
break;
}
}
// find_if方式查找(配合lambda表达式)
auto it = std::find_if(studentList.begin(),studentList.end(),
[studentID](Student &student){return student.id == studentID;});
if (it != studentList.end())
{
printf("find studentID:%s name:%sn", it->id.c_str(), it->name.c_str());
}
// find_if方式查找(配合匹配函数)
it= std::find_if(studentList.begin(),studentList.end(),MatchStudentWrapper(studentID));
if (it != studentList.end())
{
printf("find studentID:%s name:%sn", it->id.c_str(), it->name.c_str());
}
return 0;
}
运行结果:
2.4 示例三:查找vector自定义结构体中的多个指定成员
仍是通过3种方式进行对比:
- 通过for循环的方式逐个比较通过find_if方式查找,并配合lambda表达式(注意这里传递了2个参数)通过find_if方式查找,并配合匹配函数
//g++ test3.cpp -std=c++11 -o test3
#include <unistd.h>
#include <stdio.h>
#include <string>
#include <vector>
#include <algorithm>
struct Student
{
std::string id;
std::string name;
int chineseScore;
int mathScore;
};
// 用于 std::find_if 的匹配函数
bool matchStudent(const Student& student, const std::string& studentID, const std::string& studentName)
{
return student.id == studentID && student.name == studentName;
}
// 用于 std::find_if 的包装函数
struct MatchStudentWrapper
{
conststd::string& targetID;
conststd::string& targetName;
MatchStudentWrapper(conststd::string& id, conststd::string& name) : targetID(id),targetName(name) {}
bool operator()(const Student& student) const
{
return matchStudent(student, targetID, targetName);
}
};
int main()
{
printf("hellon");
std::vector<Student> studentList = {
{"S05001", "LiMing", 90, 85},
{"S05002", "ZhangHua", 92, 91},
{"S05003", "LiMing", 88, 93},
{"S05005", "ZhaoLe", 89, 96},
};
std::string studentID = "S05003";
std::string studentName = "LiMing";
// 循环查找
for (Student &it : studentList)
{
if (it.id == studentID && it.name == studentName)
{
printf("find studentID:%s name:%s, score(chinese:%d, math:%d)n", it.id.c_str(), it.name.c_str(), it.chineseScore, it.mathScore);
break;
}
}
// find_if方式查找(配合lambda表达式)
auto it = std::find_if(studentList.begin(),studentList.end(),
[studentID,studentName](Student &student){return student.id == studentID && student.name == studentName;});
if (it != studentList.end())
{
printf("find studentID:%s name:%s, score(chinese:%d, math:%d)n", it->id.c_str(), it->name.c_str(), it->chineseScore, it->mathScore);
}
// find_if方式查找(配合匹配函数)
it = std::find_if(studentList.begin(),studentList.end(),MatchStudentWrapper(studentID, studentName));
if (it != studentList.end())
{
printf("find studentID:%s name:%s, score(chinese:%d, math:%d)n", it->id.c_str(), it->name.c_str(), it->chineseScore, it->mathScore);
}
return0;
}
运行结果:
3 总结
本篇来介绍C++中find和find_if函数的使用,通过多个实例来演示。