C++17 搜索器教程:解锁高效搜索新姿势

微信图片_20250129210246.png

C++17搜索器教程:解锁高效搜索新姿势

C++17搜索器简介

在C++的发展历程中,C++17是一个重要的里程碑,它引入了诸多实用的新特性,搜索器功能便是其中之一。此功能着重对std::search算法进行了强化,使其支持多种搜索策略,极大地丰富了开发者处理数据搜索任务的手段。

经典的线性搜索作为最基础的搜索方式,在编程领域广为人知。而C++17引入的Boyer - Moore搜索算法,则为高效搜索大型数据集提供了可能。这些搜索器的出现,犹如为开发者配备了一套精良的工具,显著提升了在大型数据集中的搜索性能,让复杂的数据搜索任务变得更加轻松高效。

使用std::search和搜索器

线性搜索

线性搜索堪称搜索算法中的“基石”,其原理直白易懂:逐个检查数据集中的元素,判断其是否与目标值匹配。这种简单直接的方式,虽然在效率上略显逊色,尤其在面对大规模数据集时,但在处理小数据集或者未经过排序的数据时,却有着独特的优势——简单便捷,无需复杂的预处理。

以下是线性搜索的示例代码:

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

int main() {
    std::vector<int> data = {1, 2, 3, 4, 5, 6, 7, 8, 9};
    // 查找子序列 {4, 5}
    auto it = std::search(data.begin(), data.end(), {4, 5}.begin(), {4, 5}.end()); 
    if (it!= data.end()) {
        std::cout << "Found at position: " << std::distance(data.begin(), it) << std::endl;
    } else {
        std::cout << "Not found" << std::endl;
    }
    return 0;
}

在上述代码中,我们创建了一个整数向量data,并使用std::search算法查找子序列{4, 5}。通过std::distance函数计算找到的子序列起始位置与data起始位置的距离,从而确定子序列在data中的位置。若未找到,则输出相应提示。

Boyer - Moore搜索

Boyer - Moore算法是搜索算法领域的一颗璀璨明星,以其高效性著称。该算法的核心在于通过对模式字符串进行预处理,生成一些有用的信息,从而在搜索过程中能够跳过大量不必要的比较,大幅提升搜索速度。这一特性使得它在处理长文本或大型数据集的搜索任务时,表现格外出色。

下面是使用Boyer - Moore搜索的示例代码:

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

int main() {
    std::vector<int> data = {1, 2, 3, 4, 5, 6, 7, 8, 9};
    std::vector<int> pattern = {4, 5};
    // 使用并行策略查找模式
    auto it = std::search(std::execution::par, data.begin(), data.end(), pattern.begin(), pattern.end()); 
    if (it!= data.end()) {
        std::cout << "Found at position: " << std::distance(data.begin(), it) << std::endl;
    } else {
        std::cout << "Not found" << std::endl;
    }
    return 0;
}

在此代码中,我们同样创建了数据向量data和模式向量pattern,并使用std::search算法进行搜索。与线性搜索不同的是,这里我们使用了并行执行策略std::execution::par,借助多核处理器的力量进一步加速搜索过程。

性能优化

C++17的并行算法为搜索操作的性能优化打开了新的大门。通过指定执行策略,如std::execution::par,我们能够充分利用多核处理器的强大计算能力,实现搜索操作的并行化处理,从而显著提升搜索效率。

并行搜索示例

以下代码展示了如何巧妙运用并行策略来加速搜索操作,并精确测量搜索所需的时间:

#include <iostream>
#include <vector>
#include <algorithm>
#include <execution>
#include <chrono>

int main() {
    const size_t size = 1000000;
    std::vector<int> data(size);
    for (size_t i = 0; i < size; ++i) {
        data[i] = rand() % 100;
    }

    std::vector<int> pattern = {42, 43}; // 示例模式

    auto start = std::chrono::high_resolution_clock::now();
    // 使用并行策略搜索模式
    auto it = std::search(std::execution::par, data.begin(), data.end(), pattern.begin(), pattern.end()); 
    auto end = std::chrono::high_resolution_clock::now();
    std::chrono::duration<double> diff = end - start;

    if (it!= data.end()) {
        std::cout << "Found at position: " << std::distance(data.begin(), it) << std::endl;
    } else {
        std::cout << "Not found" << std::endl;
    }
    std::cout << "Search completed in " << diff.count() << " seconds" << std::endl;

    return 0;
}

在这段代码中,我们首先创建了一个包含一百万个随机整数的向量data,模拟大型数据集。接着定义了要搜索的模式pattern。通过记录搜索操作开始和结束的时间,利用std::chrono库精确计算出搜索所花费的时间。可以看到,使用并行执行策略std::execution::par后,在大型数据集上的搜索速度得到了明显提升。

注意事项

数据局部性

数据在内存中的布局方式对程序性能有着不可忽视的影响。确保数据具有良好的局部性,即数据在内存中是连续存储或访问模式具有一定的规律性,能够有效减少缓存未命中的次数。因为当数据局部性良好时,处理器可以更高效地从缓存中获取数据,避免频繁地从主内存中读取,从而提高程序的整体运行效率。

线程安全

在享受并行算法带来的性能提升时,我们必须时刻警惕线程安全问题。由于并行算法会同时启动多个线程进行计算,若多个线程同时访问和修改共享资源,就可能引发数据竞争,导致程序出现难以调试的错误和不可预测的行为。因此,在编写并行代码时,要避免对共享资源的直接访问,或者采用合适的同步机制来确保线程安全。

算法选择

不同的数据集具有不同的特点,选择合适的搜索算法至关重要。对于小型数据集或未排序的数据,线性搜索因其简单易用的特性,可能是一个不错的选择。而对于大型数据集,Boyer - Moore搜索器凭借其高效的搜索策略,通常能够展现出比线性搜索更高的性能优势。在实际应用中,开发者需要根据数据集的具体规模、数据分布以及搜索任务的特点,综合权衡并选择最适合的搜索算法。

希望通过本文对C++17搜索器的详细介绍,能帮助你在日常编程中更加高效地处理数据搜索任务,充分发挥C++17的强大功能。如果你对某些内容还有疑问,或者想了解更多相关知识,欢迎随时交流。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/961913.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Transformer+vit原理分析

目录 一、Transformer的核心思想 1. 自注意力机制&#xff08;Self-Attention&#xff09; 2. 多头注意力&#xff08;Multi-Head Attention&#xff09; 二、Transformer的架构 1. 整体结构 2. 编码器层&#xff08;Encoder Layer&#xff09; 3. 解码器层&#xff08;Decoder…

C语言自定义数据类型详解(二)——结构体类型(下)

书接上回&#xff0c;前面我们已经给大家介绍了如何去声明和创建一个结构体&#xff0c;如何初始化结构体变量等这些关于结构体的基础知识。下面我们将继续给大家介绍和结构体有关的知识&#xff1a; 今天的主题是&#xff1a;结构体大小的计算并简单了解一下位段的相关知识。…

【ComfyUI专栏】如何使用Git命令行安装非Manager收录节点

当前的ComfyUI的收录的自定义节点很多&#xff0c;但是有些节点属于新出来&#xff0c;或者他的应用没有那么广泛&#xff0c;Manager管理节点 有可能没有收录到&#xff0c;这时候 如果我们需要安装需要怎么办呢&#xff1f;这就涉及到我们自己安装这些节点了。例如下面的内容…

【Block总结】PKI 模块,无膨胀多尺度卷积,增强特征提取的能力|即插即用

论文信息 标题: Poly Kernel Inception Network for Remote Sensing Detection 作者: Xinhao Cai, Qiuxia Lai, Yuwei Wang, Wenguan Wang, Zeren Sun, Yazhou Yao 论文链接&#xff1a;https://arxiv.org/pdf/2403.06258 代码链接&#xff1a;https://github.com/NUST-Mac…

[OO ALV] OO ALV 基础显示

程序代码 REPORT z437_test_2025.DATA gt_spfli TYPE STANDARD TABLE OF spfli. " 内表DATA go_alv TYPE REF TO cl_gui_alv_grid. " 创建和管理ALV表格DATA gs_layout TYPE lvc_s_layo. " 存储ALV表格的布局信息*---------------------…

jQuery小游戏(二)

jQuery小游戏&#xff08;二&#xff09; 今天是新年的第二天&#xff0c;本人在这里祝大家&#xff0c;新年快乐&#xff0c;万事胜意&#x1f495; 紧接jQuery小游戏&#xff08;一&#xff09;的内容&#xff0c;我们开始继续往下咯&#x1f61c; 游戏中使用到的方法 key…

Linux的常用指令的用法

目录 Linux下基本指令 whoami ls指令&#xff1a; 文件&#xff1a; touch clear pwd cd mkdir rmdir指令 && rm 指令 man指令 cp mv cat more less head tail 管道和重定向 1. 重定向&#xff08;Redirection&#xff09; 2. 管道&#xff08;Pipes&a…

蓝桥杯之c++入门(一)【C++入门】

目录 前言5. 算术操作符5.1 算术操作符5.2 浮点数的除法5.3 负数取模5.4 数值溢出5.5 练习练习1&#xff1a;计算 ( a b ) ⋆ c (ab)^{\star}c (ab)⋆c练习2&#xff1a;带余除法练习3&#xff1a;整数个位练习4&#xff1a;整数十位练习5&#xff1a;时间转换练习6&#xff…

51单片机开发:定时器中断

目标&#xff1a;利用定时器中断&#xff0c;每隔1s开启/熄灭LED1灯。 外部中断结构图如下图所示&#xff0c;要使用定时器中断T0&#xff0c;须开启TE0、ET0。&#xff1a; 系统中断号如下图所示&#xff1a;定时器0的中断号为1。 定时器0的工作方式1原理图如下图所示&#x…

【设计测试用例自动化测试性能测试 实战篇】

&#x1f308;个人主页&#xff1a;努力学编程’ ⛅个人推荐&#xff1a; c语言从初阶到进阶 JavaEE详解 数据结构 ⚡学好数据结构&#xff0c;刷题刻不容缓&#xff1a;点击一起刷题 &#x1f319;心灵鸡汤&#xff1a;总有人要赢&#xff0c;为什么不能是我呢 设计测试用例…

指针(C语言)从0到1掌握指针,为后续学习c++打下基础

目录 一&#xff0c;指针 二&#xff0c;内存地址和指针 1&#xff0c;什么是内存地址 2&#xff0c;指针在不同系统下所占内存 三&#xff0c;指针的声明和初始化以及类型 1,指针的声明 2,指针 的初始化 1&#xff0c; 初始化方式优点及适用场景 4,指针的声明初始化类型…

利用Redis实现数据缓存

目录 1 为啥要缓存捏&#xff1f; 2 基本流程&#xff08;以查询商铺信息为例&#xff09; 3 实现数据库与缓存双写一致 3.1 内存淘汰 3.2 超时剔除&#xff08;半自动&#xff09; 3.3 主动更新&#xff08;手动&#xff09; 3.3.1 双写方案 3.3.2 读写穿透方案 3.3.…

MySQL(高级特性篇) 14 章——MySQL事务日志

事务有4种特性&#xff1a;原子性、一致性、隔离性和持久性 事务的隔离性由锁机制实现事务的原子性、一致性和持久性由事务的redo日志和undo日志来保证&#xff08;1&#xff09;REDO LOG称为重做日志&#xff0c;用来保证事务的持久性&#xff08;2&#xff09;UNDO LOG称为回…

S4 HANA明确税金本币和外币之间转换汇率确定(OBC8)

本文主要介绍在S4 HANA OP中明确明确税金本币和外币之间转换汇率确定(OBC8)相关设置。具体请参照如下内容&#xff1a; 明确税金本币和外币之间转换汇率确定(OBC8) 以上配置&#xff0c;我们可以根据不同公司代码所配置的使用不同的汇率来对税金外币和本币之间进行换算。来针对…

SpringBoot 日志与配置文件

SpringBoot 配置文件格式 Properties 格式 Component ConfigurationProperties(prefix "person") //和配置文件person前缀的所有配置进行绑定 Data public class Person {private String name;private Integer age;private Date birthDay;private Boolean like;pr…

oracl:数据查询语言DQL

SQL&#xff08;Structured Query Language&#xff0c;结构化查询语言&#xff09;是一种用于管理和操作关系数据库的标准编程语言。 sql分类: 基本查询语法 数据查询语言&#xff08;DQL - Data Query Language&#xff09; 查询的关键词 select where对查询结果进行过滤…

Hive:窗口函数(1)

窗口函数 窗口函数OVER()用于定义一个窗口&#xff0c;该窗口指定了函数应用的数据范围 对窗口数据进行分区 partition by 必须和over () 一起使用, distribute by经常和sort by 一起使用,可以不和over() 一起使用.DISTRIBUTE BY决定了数据如何分布到不同的Reducer上&#xf…

多目标优化策略之一:非支配排序

多目标优化策略中的非支配排序是一种关键的技术,它主要用于解决多目标优化问题中解的选择和排序问题,确定解集中的非支配解(也称为Pareto解)。 关于什么是多目标优化问题,可以查看我的文章:改进候鸟优化算法之五:基于多目标优化的候鸟优化算法(MBO-MO)-CSDN博客 多目…

神经网络和深度学习

应用 类型 为什么近几年飞速发展 数据增长&#xff0c;算力增长&#xff0c;算法革新 逻辑回归 向量化 浅层神经网络(Shallow neural network) 单条训练数据前向传播计算表达式 batch训练数据前向传播计算表达式 反向传播计算表达式 参数随机初始化 不能全部设为0 原因是同一…

生成模型:扩散模型(DDPM, DDIM, 条件生成)

扩散模型的理论较为复杂&#xff0c;论文公式与开源代码都难以理解。现有的教程大多侧重推导公式。为此&#xff0c;本文通过精简代码&#xff08;约300行&#xff09;&#xff0c;从代码运行角度讲解扩散模型。 本文包括扩散模型的3项技术复现&#xff1a; 1.DDPM (Denoising…