C++学习笔记(三十七)——STL之搜索算法

STL 算法分类:

类别常见算法作用
排序sortstable_sortpartial_sortnth_element排序
搜索findfind_ifcountcount_ifbinary_search查找元素
修改copyreplacereplace_ifswapfill修改容器内容
删除removeremove_ifunique删除元素
归约for_eachaccumulate处理数据
合并mergeset_unionset_intersection处理有序序列
排列组合next_permutationprev_permutation生成排列
堆操作push_heappop_heapmake_heapsort_heap处理堆

STL 搜索算法

C++的STL 中,提供了一些用于搜索容器中元素的算法,位于 <algorithm> 头文件中。
常见的搜索算法包括 findbinary_searchfind_if 等。

算法名称功能描述时间复杂度空间复杂度适用场景
find查找容器中第一个与指定值相等的元素O(n)O(1)在无序容器中查找元素
find_if查找容器中第一个满足指定条件的元素O(n)O(1)查找满足特定条件的元素
count统计某个元素在范围内出现的次数O(n)O(1)统计某个元素出现的次数
count_if统计满足特定条件的元素数量O(n)O(1)统计符合条件的元素数量
binary_search查找容器中是否存在某个元素(要求容器已排序)O(log n)O(1)在已排序的容器中查找元素
lower_bound查找容器中第一个不小于指定值的元素O(log n)O(1)在已排序的容器中查找不小于指定值的元素
upper_bound查找容器中第一个大于指定值的元素O(log n)O(1)在已排序的容器中查找大于指定值的元素
search查找一个子序列在另一个序列中的首次出现O(n * m)O(1)查找子序列在容器中的位置
search_n查找某个值连续出现 n 次的子序列O(n)O(1)查找某个值连续出现的子序列

(1) find

  • 功能:在容器中查找第一个与指定值相等的元素。
  • 时间复杂度O(n),其中 n 是容器中的元素数。
  • 空间复杂度O(1),原地操作。

示例:

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

int main() {
    vector<int> vec = { 5, 2, 8, 3, 1 };

    auto it = find(vec.begin(), vec.end(), 3); // 查找值为 3 的元素

    if (it != vec.end())
    {
        cout << "找到元素: " << *it << endl;  // 输出:找到元素: 3
    }
    else
    {
        cout << "元素未找到" << endl;
    }

    system("pause");
    return 0;
}

注意:

  • find适用于顺序容器(如 vectorlist 等)。

(2)find_if

  • 功能:在容器中查找第一个满足给定条件的元素。
  • 时间复杂度O(n),其中 n 是容器中的元素数。
  • 空间复杂度O(1),原地操作。

示例:

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

bool is_even(int n) 
{
    return n % 2 == 0;  // 判断是否为偶数
}

int main() {
    vector<int> vec = { 5, 2, 8, 3, 1 };

    auto it = find_if(vec.begin(), vec.end(), is_even); // 查找第一个偶数

    if (it != vec.end())
    {
        cout << "找到偶数: " << *it << endl;  // 输出:找到偶数: 2
    }
    else
    {
        cout << "未找到偶数" << endl;
    }

    system("pause");
    return 0;
}

注意:

  • find 不同,find_if 是基于条件的查找,使用一个谓词(即一个返回布尔值的函数或仿函数)来判断元素是否满足条件。

(3) count

  • 功能:计算给定范围内某个元素出现的次数。
  • 时间复杂度O(n),其中 n 是范围中的元素数量。
  • 空间复杂度O(1),原地操作。

示例:

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

int main() {
    vector<int> vec = { 10, 20, 10, 40, 10 };

    // 统计 10 出现的次数
    int num = count(vec.begin(), vec.end(), 10);
    cout << "元素 10 出现了 " << num << " 次。" << endl;

    system("pause");
    return 0;
}

注意:

  • count适用于,当需要统计某个元素在容器中出现的次数时使用。

(4) count_if

  • 功能:计算给定范围内满足特定条件的元素的数量。
  • 时间复杂度O(n),其中 n 是范围中的元素数量。
  • 空间复杂度O(1),原地操作。

示例:

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

bool is_even(int n)
{
    return n % 2 == 0;
}

int main() {
    vector<int> vec = { 1, 2, 3, 4, 5, 6 };

    // 统计偶数元素的数量
    int num = count_if(vec.begin(), vec.end(), is_even);
    cout << "有 " << num << " 个偶数元素。" << endl;

    system("pause");
    return 0;
}

注意:

  • count_if适用于,当需要统计满足某个条件的元素数量时使用。

(5) binary_search

  • 功能:判断容器中是否存在某个元素,要求容器必须已经是有序的。
  • 时间复杂度O(log n)n 是容器中的元素数。
  • 空间复杂度O(1),原地操作。

示例:

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

int main() {
    vector<int> vec = { 1, 2, 3, 5, 8 };  // 已经排序

    bool found = binary_search(vec.begin(), vec.end(), 3); // 查找是否有 3
    cout << (found ? "找到" : "未找到") << endl;  // 输出:找到

    found = binary_search(vec.begin(), vec.end(), 4); // 查找是否有 4
    cout << (found ? "找到" : "未找到") << endl;  // 输出:未找到

    system("pause");
    return 0;
}

注意:

  • binary_search适用于有序容器。它返回布尔值,表示是否找到目标元素。

(6)lower_bound

  • 功能:返回指向容器中第一个不小于指定值的元素的迭代器。
  • 时间复杂度O(log n)n 是容器中的元素数。
  • 空间复杂度O(1),原地操作。

示例:

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

int main() {
    vector<int> vec = { 1, 2, 3, 5, 8 };  // 已经排序

    auto it = lower_bound(vec.begin(), vec.end(), 3); // 查找大于等于 3 的第一个元素

    if (it != vec.end()) 
    {
        cout << "找到元素: " << *it << endl;  // 输出:找到元素: 3
    }
    else
    {
        cout << "未找到元素" << endl;
    }

    system("pause");
    return 0;
}

注意:

  • lower_bound适用于有序容器。它可以用来查找某个值或第一个大于等于该值的元素。

(7)upper_bound

  • 功能:返回指向容器中第一个大于指定值的元素的迭代器。
  • 时间复杂度O(log n)n 是容器中的元素数。
  • 空间复杂度O(1),原地操作。

示例:

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

int main() {
    vector<int> vec = { 1, 2, 3, 5, 8 };  // 已经排序

    auto it = upper_bound(vec.begin(), vec.end(), 3); // 查找大于 3 的第一个元素

    if (it != vec.end())
    {
        cout << "找到元素: " << *it <<endl;  // 输出:找到元素: 5
    }
    else
    {
        cout << "未找到元素" << endl;
    }

    system("pause");
    return 0;
}

注意:

  • upper_bound适用于有序容器。它返回一个迭代器,指向第一个比指定值大的元素。

(8) search

  • 功能:在一个范围中查找另一个范围(子序列)的第一次出现。
  • 时间复杂度O(n * m),其中 n 是第一个范围的大小,m 是第二个范围的大小。
  • 空间复杂度O(1)

示例:

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

int main() {
    vector<int> vec = { 1, 2, 3, 4, 5, 6 };
    vector<int> subvec = { 3, 4 };

    // 查找子序列 subvec 在 vec 中的首次出现
    auto it = std::search(vec.begin(), vec.end(), subvec.begin(), subvec.end());
    if (it != vec.end())
    {
        cout << "子序列 subvec 在 vec 中的首次出现的位置: " << distance(vec.begin(), it) << endl;
    }
    else
    {
        cout << "未找到子序列subvec" << endl;
    }

    system("pause");
    return 0;
}

注意:

  • search适用于查找一个子序列在另一个序列中的位置。

(9) search_n

  • 功能:在给定范围内查找一个值连续出现的子序列(即连续 n 次相同的元素)。
  • 时间复杂度O(n),其中 n 是范围中的元素数量。
  • 空间复杂度O(1)

示例:

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

int main() {
    vector<int> vec = { 1, 2, 2, 2, 3, 4 };

    // 查找连续出现 3 次的元素 2
    auto it = search_n(vec.begin(), vec.end(), 3, 2);
    if (it != vec.end())
    {
        cout << "连续出现 3 次的元素 2 的首次出现的位置: " << distance(vec.begin(), it) << endl;
    }
    else
    {
        cout << "未找到连续出现 3 次的元素 2" << endl;
    }

    system("pause");
    return 0;
}

注意:

  • search_n适用于查找某个值连续出现的子序列。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

奕天者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值