判断vector中是否存在某元素的多种方法

工作中经常遇见的一个场景:判断某个元素是否在vector容器中。

当然,会有很多种方法,由内置数据类型到自定义数据类型,下面简单总结一下。

【1】内置数据类型

代码胜过一切文档。如下示例代码:

#include <iostream>
#include <vector>
#include <string>

// 为了便于示例,声明全局容器
std::vector<std::string> strVec;

void methods(const std::string& target)
{
    // 方法一:遍历容器,查找相等元素判断是否存在
    {
        for (const auto& item : strVec)
        {
            if (item == target)
            {
                std::cout << "method1: find " << target << " exists." << std::endl;
                break;
            }
        }
    }
    // 方法二:获取元素个数,通过个数判断是否存在
    {
        int nCount = std::count(strVec.begin(), strVec.end(), target);
        if (nCount > 0)
        {
            std::cout << "method2: find " << target << " exists." << std::endl;
        }
    }
    // 方法三:查询元素迭代器,通过迭代器有效性判断是否存在
    {
        auto iter = std::find(strVec.begin(), strVec.end(), target);
        if (iter != strVec.end())
        {
            std::cout << "method3: find " << target << " exists." << std::endl;
        }
    }
    // 方法四:查询相等元素的迭代器,通过迭代器有效性判断是否存在
    {
        auto iter = std::find_if(strVec.begin(), strVec.end(), [&](const std::string& item)->bool
            { return (item == target); });
        if (iter != strVec.end())
        {
            std::cout << "method4: find " << target << " exists." << std::endl;
        }
    }
}

int main()
{
    strVec = { "C", "C++", "Java", "Python", "Lua", "Sql" };
    // 场景1:查找Ruby
    std::cout << "Find Ruby" << std::endl;
    methods("Ruby");
    // 场景2:查找C++
    std::cout << "Find C++" << std::endl;
    methods("C++");

    system("pause");
    return 0;
}

// result
/*
Find Ruby
Find C++
method1: find C++ exists.
method2: find C++ exists.
method3: find C++ exists.
method4: find C++ exists.
*/

【2】自定义数据类型

代码胜过一切文档。如下示例代码:

#include <iostream>
#include <map>
#include <string>
#include <vector>

struct Student
{
    std::string code;  // 学号(唯一性标识)
    int grade;         // 年级
    std::map<std::string, double> scores; // <科目,成绩>

    bool operator==(const Student& obj) const
    {
        return obj.code == code; // 只要学号相同即可
    }
};

// 为了便于示例,声明全局容器
std::vector<Student> vecStu;

void methods(const Student& target)
{
    // 方法一:遍历容器,查找相等元素判断是否存在
    {
        for (const auto& item : vecStu)
        {
            if (item == target)
            {
                std::cout << "method1: find exists." << std::endl;
                break;
            }
        }
    }
    // 方法二:获取元素个数,通过个数判断是否存在
    {
        int nCount = std::count(vecStu.begin(), vecStu.end(), target);
        if (nCount > 0)
        {
            std::cout << "method2: find exists." << std::endl;
        }
    }
    // 方法三:查询元素迭代器,通过迭代器有效性判断是否存在
    {
        auto iter = std::find(vecStu.begin(), vecStu.end(), target);
        if (iter != vecStu.end())
        {
            std::cout << "method3: find exists." << std::endl;
        }
    }
    // 方法四:查询相等元素的迭代器,通过迭代器有效性判断是否存在
    {
        if (std::find_if(vecStu.begin(), vecStu.end(), [&](const Student& obj)->bool
            { return (obj == target); }) != vecStu.end())
        {
            std::cout << "method4: find exists." << std::endl;
        }
    }
}

int main()
{
    vecStu.push_back({ "080605109", 6, { {"English", 100}, {"China", 100} } });
    vecStu.push_back({ "080605110", 7, { {"English", 99}, {"China", 70} } });
    vecStu.push_back({ "080605111", 8, { {"English", 98}, {"China", 69} } });
    vecStu.push_back({ "080605112", 6, { {"English", 97}, {"China", 68} } });
    vecStu.push_back({ "080605113", 7, { {"English", 96}, {"China", 67} } });
    Student obj = { "080605114", 8, { {"English", 95}, {"China", 66} } };
    vecStu.push_back(obj);

    // 场景1:查找学号为[0806005109]的学生,我们暂不关注成绩
    std::cout << "Find code: 0806005108" << std::endl;
    methods(Student{ "0806005108", {} });
    // 场景2:查找学号为[0806005114]的学生,我们暂不关注成绩
    std::cout << "Find code: 0806005114" << std::endl;
    methods(obj);
    // 场景3:不想通过学号,只想查找六年级,是否存在英语和语文全为满分的学生
    auto iter = std::find_if(vecStu.begin(), vecStu.end(), [&](const Student& obj)->bool
        { return (obj.grade == 6 &&
            obj.scores.find("English")->second == 100 &&
            obj.scores.find("China")->second == 100); });
    if (iter != vecStu.end())
    {
        std::cout << "method: find 100 exists." << std::endl;
    }

    return 0;
}

// result
/*
Find code: 0806005108
Find code: 0806005114
method1: find exists.
method2: find exists.
method3: find exists.
method4: find exists.
method: find 100 exists.
*/

注意:自定义数据类型,必须重载==符号。

原因很简单:遇见这种场景,计算机弄不明白你想让它以什么标准来判断两个对象相等,所以你得给它确定了相等的标准或准则。

综上所述,再强调一点:针对自定义数据类型,使用std::find_if方法,显而易见,自由度很大。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值