【c++常用查找算法】

本文已参与「掘力星计划」,赢取创作大礼包,挑战创作激励金。

常用查找算法

【简介】:

  •     find; // 查找元素 
  •     find_if; // 按条件查找元素
  •     adjacent_find; // 查找相邻重复元素
  •     binary_search; // 二分查找法
  •     count; // 统计元素个数
  •     count_if; // 按条件统计元素个数

find

【功能】:

  查找指定元素,找到返回指定元素的迭代器,找不到返回结束迭代器end()
复制代码

【函数原型】:

find(iterator begin,iterator end,value);

    // 按值查找元素,找到返回指定位置迭代器,找不到返回结束迭代器位置

    // begin 开始迭代器

    // end 结束迭代器

    // value 查找的元素
复制代码

【demo】:

#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
using namespace std;

class Person
{
public:
    Person(string name, int age)
    {
        this->m_Name = name;
        this->m_Age = age;
    }
    
    // 重载 ==
    bool operator==(const Person &p)
    {
        if (this->m_Name == p.m_Name && this->m_Age == p.m_Age)
        {
            return true;
        }
        return false;
    }
public:

    string m_Name;

    int m_Age;
};

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 << "找到了 " << *it << endl;
    }
    else
    {
        cout << "未找到" << endl;
    }
}

void test02()
{
    vector<Person> v;
    Person p1("张三"20);
    Person p2("李四"19);
    Person p3("王五"21);
    Person p4("赵六"22);
    v.push_back(p1);
    v.push_back(p2);
    v.push_back(p3);
    v.push_back(p4);
    
    Person targetP("王五"21);
    vector<Person>::iterator it = find(v.begin(), v.end(), targetP);
    if (it != v.end())
    {
        cout << "找到了 " << it->m_Name << "," << it->m_Age << endl;
    }
    else
    {
        cout << "未找到" << endl;
    }
}

int main()
{
    test01();
    test02();
    return 0;
}
复制代码

小结:利用find可以在容器中找到指定的元素,返回值是迭代器

find_if

【功能】:

按条件查找元素
复制代码

【函数原型】:

find_if(iterator begin,iterator end,_Pred);

    // 按值查找元素,找到返回位置迭代器,找不到返回结束位置迭代器

    // begin 开始迭代器

    // end 结束迭代器

    // _Pred 函数或者谓词(返回bool类型的仿函数)
复制代码

【demo】:

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

// 内置数据类型
class GreaterFive
{
public:
    bool operator()(int v)
    {
        return v > 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 << "找打了大于5的数字: " << *it << endl;
    }
    else
    {
        cout << "未找到" << endl;
    }
}

class Person
{
public:
    Person(string name, int age)
    {
        this->m_Name = name;
        this->m_Age = age;
    }
public:
    string m_Name;
    int m_Age;
};

class Greater20
{
public:
    bool operator()(Person &p)
    {
        return p.m_Age > 20;
    }
};

void test02()
{

    Person p1("张三"20);
    Person p2("李四"22);
    Person p3("王五"19);
    vector<Person> v;
    v.push_back(p1);
    v.push_back(p2);
    v.push_back(p3);

    vector<Person>::iterator it = find_if(v.begin(), v.end(), Greater20());
    if (it != v.end())
    {
        cout << "找打了大于20岁的: " << it->m_Name << "," << it->m_Age << endl;
    }
    else
    {
        cout << "未找到" << endl;
    }
}

int main()
{
    test01();
    test02();
    return 0;
}
复制代码

小结:find_if按条件查找是查找更加灵活,提供的仿函数可以改变不同的策略

adjacent_find

【功能】:

查找相邻重复元素
复制代码

【函数原型】:

adjacent_find(iterator begin,iterator end);

    // 查找相邻重复元素,返回相邻元素的第一个位置的迭代器

    // begin 开始迭代器

    // end 结束迭代器
复制代码

【demo】:

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;
void test01()
{
    vector<int> v;
    v.push_back(0);
    v.push_back(1);
    v.push_back(2);
    v.push_back(2);
    v.push_back(3);
    v.push_back(3);

    // 查找相邻重复元素
    vector<int>::iterator it = adjacent_find(v.begin(), v.end());
    if (it != v.end())
    {
        cout << "找到了重复的元素:" << *it << endl;
    }
    else
    {
        cout << "未找到重复的元素" << endl;
    }
}

int main()
{
    test01();
    return 0;
}
复制代码

小结:面试题中若出现查找相邻重复元素,可以使用STL中的adjacent_find算法

binary_search

【功能】:

查找指定元素是否存在
复制代码

【函数原型】:

bool binary_search(iterator begin,iterator end,value);

    // 查找指定的元素,查到返回true,否则返回false;

    // 注意:在**无序序列**中**不可用**

    // begin 开始迭代器

    // end 结束迭代器

    // value 查找的元素
复制代码

【demo】:

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;
void test01()
{

    vector<int> v;
    for (int i = 0; i < 10; i++)
    {
        v.push_back(i);
    }

    // 二分查找
    bool ret = binary_search(v.begin(), v.end(), 2);
    if (ret)
    {
        cout << "找到了" << endl;
    }
    else
    {
        cout << "未找到" << endl;
    }
}
int main()
{
    test01();
    return 0;
}
复制代码

小结:二分查找效率很高,但是查找的容器中的元素必须是有序的

count

【功能】:

统计元素个数
复制代码

【函数原型】:

count(iterator begin,iterator end,value);

    // 统计元素出现的次数

    // begin 开始迭代器

    // end 结束迭代器

    // value 统计的元素
复制代码

【demo】:

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

// 自定义数据类型
class Person
{
public:
    Person(string name, int age)
    {
        this->m_Name = name;
        this->m_Age = age;
    }
    bool operator==(const Person &p)
    {
        if (this->m_Age == p.m_Age)
        {
            return true;
        }
        return false;
    }

public:
    string m_Name;
    int m_Age;
};

void test01()
{
    vector<int> v;
    v.push_back(0);
    v.push_back(0);
    v.push_back(1);
    v.push_back(2);
    v.push_back(2);
    v.push_back(3);

    int num = count(v.begin(), v.end(), 2);
    cout << "2出现了:" << num << "次" << endl;
}

void test02()
{
    Person p1("张三", 20);
    Person p2("李四", 20);
    Person p3("王五", 20);
    vector<Person> v;
    v.push_back(p1);
    v.push_back(p2);
    v.push_back(p3);

    Person pTarget("小明", 20);
    int num = count(v.begin(), v.end(), pTarget);
    cout << "20岁的人有 " << num << "人" << endl;
}

int main()
{
    test01();
    test02();
    return 0;
}
复制代码

:统计自定以数据类型时,需要配合重载 operator==

count_if

【功能】:

按条件统计元素个数
复制代码

【函数原型】:

count_if(iterator begin,iterator end,_Pred);

    // 按条件统计元素出现的次数

    // begin 开始迭代器

    // end 结束迭代器

    // _Pred 谓词(仿函数)
复制代码

【demo】:

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

using namespace std;

class GreaterFive
{
public:
    bool operator()(int v)
    {
        return v > 5;
    }
};

// 自定义数据类型
class Person
{
public:
    Person(string name, int age)
    {
        this->m_Name = name;
        this->m_Age = age;
    }

public:
    string m_Name;
    int m_Age;
};
class AgeGreater20
{
public:
    bool operator()(Person &p)
    {
        return p.m_Age > 20;
    }
};

void test01()
{
    vector<int> v;
    for (int i = 0; i < 10; i++)
    {
        v.push_back(i);
    }

    int num = count_if(v.begin(), v.end(), GreaterFive());
    cout << "大于5的数有" << num << "个" << endl;
}

void test02()
{
    Person p1("张三", 20);
    Person p2("李四", 21);
    Person p3("王五", 22);
    Person p4("赵六", 23);

    vector<Person> v;
    v.push_back(p1);
    v.push_back(p2);
    v.push_back(p3);
    v.push_back(p4);

    int num = count_if(v.begin(), v.end(), AgeGreater20());
    cout << "年龄大于20的有" << num << "人" << endl;
}
int main()
{
    test01();
    test02();
    return 0;
}
复制代码

欢迎在评论区讨论,掘金官方将在掘力星计划活动结束后,在评论区抽送100份掘金周边,抽奖详情见活动文章

猜你喜欢

转载自juejin.im/post/7017355551029870622
今日推荐