当前位置:首页 > 公众号精选 > 码农爱学习

本篇来介绍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 
#include 
#include 
#include 

int main()
{
printf("hello\n");

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 numberList\n", it);
break;
}
}

// find方式查找
auto it = std::find(numberList.begin(),numberList.end(),num);
if (it != numberList.end())
{
printf("find num:%d in numberList\n", *it);
}

return0;
}

运行结果:

1.3 查找字符串 

find也可用于在字符串查找字符和子串。

//g++ test2.cpp -std=c++11 -o test2
#include 
#include 
#include 
#include 

int main()
{
printf("hello\n");

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' 首次出现的位置是 %zu\n", r1);
    } 
else
{
        printf("r1: 未找到字符 'l'\n");
    }

    if (r2 != std::string::npos) 
{  
printf("r2: 字符 'a' 首次出现的位置是 %zu\n", r2);
    } 
else
{
        printf("r2: 未找到字符 'a'\n");
    }

    if (r3 != std::string::npos) 
{
        printf("r3: 子字符串 \"ll\" 首次出现的位置是 %zu\n", r3);
    } 
else
{
        printf("r3: 未找到子字符串 \"ll\"\n");
    }

    if (r4 != std::string::npos) 
{
        printf("r4: 子字符串 \"abc\" 首次出现的位置是 %zu\n", 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 
#include 
#include 
#include 

bool isEven(int num) 
{
    return num % 2 == 0;
}

int main()
{
    printf("hello\n");

    std::vector<int> numberList = {1, 3, 5, 7, 8, 9};

    // 循环查找
    for (int &it : numberList)
    {
        if (isEven(it))
        {
        printf("find even:%d\n", 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:%d\n", *it);
    }

    // find_if方式查找(配合匹配函数)
    it = std::find_if(numberList.begin(),numberList.end(),isEven);

    if (it != numberList.end())
    {
        printf("find even:%d\n", *it);
    }

    return0;
}

运行结果:

2.3 示例二:查找vector自定义结构体中的指定成员 

仍是通过3种方式进行对比:

  • 通过for循环的方式逐个比较
  • 通过find_if方式查找,并配合lambda表达式(注意这里传递了1个参数)
  • 通过find_if方式查找,并配合匹配函数
//g++ test2.cpp -std=c++11 -o test2
#include 
#include 
#include 
#include 
#include 

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("hello\n");

    std::vector 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:%s\n", 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:%s\n", 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:%s\n", 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 
#include 
#include 
#include 
#include 

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("hello\n");

    std::vector 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函数的使用,通过多个实例来演示。

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除( 邮箱:macysun@21ic.com )。
关闭