用于程序搜索的智能融合算法的设计与实现(C++,已用于程序中)

该程序搜索算法是我最近写的软件中使用到的算法,软件的项目地址如下:https://github.com/ghost-him/QuickLaunch/。建议打开源码,找到对应的代码后再阅读本文章。

该算法已经应用在软件中,并且取得了令我自己很满意的效果。

前言结束,以下是正文:


程序搜索算法介绍

该程序使用了融合算法来实现查找目标应用程序。搜索算法的实现位于model文件夹下的database类中。可以对着源码来查看本文档。

该搜索算法的特点是:

  • 可以用极少的字符匹配超长字符
  • 支持拼音(全拼与首字母拼音)搜索
  • 支持模糊查找

算法的总体流程

先对算法的运行流程熟悉后再对具体实现有所了解。

  1. 程序在初始化时,会根据配置读取电脑上安装的程序,并向database类中添加对应的记录。(通过insertProgramInfo函数添加)。
  2. 用户在按下alt + space后,会弹出来搜索栏,每当用户向其中输入一个字符(或删除一个字符),则会调用一次database类中的updateProgramInfo函数,而传入的参数则是当前搜索栏中的字符。
    1. updateProgramInfo会计算当前用户输入的字符串与存储的所有的记录的匹配度(programLevel
    2. 根据匹配度对所有的内容进行从小到大的排序
  3. uiController会选择指定的前几个记录作为显示项,将其添加到QListWidget中,显示给用户。

从以上的流程可以知道:

  • 每当用户输入一个字符,程序都会运行一次搜索算法
  • 算法的核心是根据用户输入的字符串计算每一个programNodeprogramLevel的值
  • 显示出来的匹配项为所有的programNodeprogramLevel最小的几个。

数据结构定义

对于一个程序,使用ProgramNode来维护,该结构体的定义如下:

struct ProgramNode {std::wstring programName;std::wstring compareName;std::wstring pinyinName;std::wstring firstLatterName;std::wstring programPath;double programLevel;int stableLevel;int launchTime;const bool operator<(const ProgramNode& other) const {if (programLevel != other.programLevel) {return programLevel < other.programLevel;} else if (launchTime != other.launchTime) {return launchTime > other.launchTime;} else {return compareName < other.compareName;}}
};

以下是字段的解释:

  • programName:该字段用于在界面中显示程序的名字,不参与搜索算法。
  • compareName:该字段用于精确匹配程序的名字。在插入数据时,会先进行预处理:
    • 将大字字母全部转换为小写字母(OneNote -> onenote
    • 将括号内的内容全部去除(qt creator 13.0.2 (community)->qt creator 13.0.2
  • pinyinName:该字段用于存储中文名字的程序的拼音(网易云音乐->wang yi yun yin le,因 字存在多音字的情况,所以无法正确匹配拼音)
  • firstLatterName:该字段用于存储中文名字的程序的拼音首字母(网易云音乐->wyyyl
  • programPath:该字段用于存储该程序在磁盘中的位置
  • programLevel:该字段用于存储该程序的总权重
  • stableLevel:该字段用于存储程序的固定权重
  • launchTime:该字段用于存储程序的启动次数

具体流程

programLevel的值取决于以下三个值:directValuepinyinValuefirstLatterValue,其意思分别是:精确匹配的匹配值,使用拼音匹配的匹配值,使用拼音首字母匹配的匹配值。而programLevel的值取这三个中最小的那个。

至于三个值的计算均由computeCombinedValue函数完成,该函数也是程序搜索算法的核心。

该函数有两个参数:storeNameinputNamestoreName表示存储的程序的名字,而inputName表示用户输入的程序的名字。融合算法由以下三种子算法构成:

  1. 最短编辑距离变体
  2. KMP算法变体
  3. 最长公共子序列变体

除了以上的子算法,还有其他的条件来确保匹配:

  • 判断输入的长度是否大于程序的名字的长度(精确名字与拼音名字的最大值),如果已经大于程序的长度了,则一定不是该程序(在运行时,如果不设置该条件,则会存在无法匹配到拥有长程序名的程序)。

最短编辑距离变体

最短编辑距离变体算法由editSubstrDistance函数实现,左边为内存中存储的字符串,而右边为用户输入的字符串。

该函数的计算流程是:当用户输入的字符串中,最少经过[添加一个字符|删除一个字符|修改一个字符]几次后可以变为左边的子字符串。并且计算修改的次数占总输入数据长度的比值 x x x(通过除法,将值映射为[0-1]区间内)。并使用 y ( x ) = 25 ∗ 3 3 ∗ x − 2 y(x)=25*3^{3*x-2} y(x)=2533x2函数将其映射到 [ 2.7 , 75 ] [2.7, 75] [2.7,75]之间。(该函数没有特别设计,关键是一个指数函数,且 y ( x ) y(x) y(x)足够小, y ( 1 ) y(1) y(1)足够大,凹函数)

至于为什么这样设计,可以这样理解:如果我输入了5个字符,比如steam,但是这5个字符,需要修改4次,才可以成为deepl的一个子字符串,那么有极大的概率查找的不是这个程序。相反,我输入的这5个字符无须修改就可以成为steam的一个子字符串,那么说明我查找的程序很有可能就是这个程序。综上所述,steamprogramLevel会比deeplprogramLevel小。

以下是计算的过程,输入的字符串为steam

  • 对于程序steam来说:修改0次(steam->steam),则比值min_operations 0 / 5 = 0 0/5=0 0/5=0。再经过函数的映射,可以得到directValue2.77
  • 对于程序deepl来说:修改4次(steam->deepl),则比值min_operations 4 / 5 = 0.8 4/5=0.8 4/5=0.8。再经过函数的映射,可以得到directValue38.79

为什么要使用指数函数将其扩大?

  • 为了方便后续的处理。当输入steam时,可能会匹配其他的选择,比如steam support center。此时,如果单纯的使用该算法作为判断依据,则无法处理这个情况(两者的值一样)

KMP算法变体

KMP算法变体由kmp函数实现,其具体的处理过程如下:

  1. 如果输入的字符串是一个程序的子字符串,则返回其输入长度的负值。
  2. 如果输入的字符串不但是程序的子字符串,同时程序还是以该字符串开头的,则返回2倍的负的输入长度

通过该算法可以实现:如果我输入command,那么command prompt的值会比developer command prompt for vs 2022小,可以实现前者排在后者的上面,优先被选中。

注意:该函数返回的值是一个负值。相加时可以减少programLevel的值,从而提高匹配程序的排名。

最长公共子序列变体

最长公共子序列算法求的是输入字符串与目标字符串的最长的公共子序列的长度。比如:

text1 = "abcde", text2 = "ace" 
输出:3  
解释:最长公共子序列是 "ace" ,它的长度为 3 。

以上数据来源:力扣

在本程序中,使用LCS函数实现。当该函数计算完子序列的长度previous[n]时,会计算该子序列相对于输入字符串与目标字符串的差值。即:m + n - 2 * previous[n]。这样可以防止输入steam时,steamsteam support center的值一样,可以优先匹配长度更短的字符串。同时,使用该算法可以弥补最短编辑距离变体的缺点。由于该算法对于结果的影响较大(比如以上例子,匹配steam support center时,该函数运行的结果为15,会对结果造成很大的影响,可能排在第二位的选项不是该程序而是其他完全不相关的程序),所以在融合算法中,差其权重设置为了0.2,从而来减小影响。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

TIOBE 6月榜单出炉!编程语言地位大洗牌,谁才是王?

C历史上首次超越C&#xff01;&#xff01;&#xff01; TIOBE 公布了 2024 年 6 月编程语言的排行榜&#xff1a;https://www.tiobe.com/tiobe-index/ 排行榜 以下列出的语言代表了第51至第100名。由于它们之间的差异相对较小&#xff0c;编程语言仅以字母顺序列出。 ABC, A…

如何实现HPC数据传输的高效流转,降本增效?

高性能计算&#xff08;HPC&#xff09;在多个行业中都有应用&#xff0c;涉及到HPC数据传输的行业包括但不限于&#xff1a; 1.科学研究&#xff1a;在物理学、化学、生物学、地球科学等领域进行模拟和建模。 2.工程和产品设计&#xff1a;进行复杂系统的设计和分析&#xf…

CesiumJS【Basic】- #023 加载webm文件(Entity方式)

文章目录 加载webm文件(Entity方式)1 目标2 代码2.1 main.ts3 资源文件加载webm文件(Entity方式) 1 目标 使用Entity方式加载webm文件 2 代码 2.1 main.ts /** @Author: alan.lau* @Date: 2024-06-16 11:15:48* @LastEditTime: 2024-06-16 11:43:02* @LastEditors: al…

江山欧派杯2024全国华佗五禽戏线上线下观摩交流比赛在亳州开幕

6月28日&#xff0c;2024全国华佗五禽戏线上线下观摩交流比赛在安徽省亳州市开幕。 此次比赛是由安徽省亳州市文化旅游体育局和安徽省非物质文化遗产保护中心主办、亳州市华佗五禽戏协会&#xff08;国家级非遗华佗五禽戏保护单位&#xff09;和亳州市传统华佗五禽戏俱乐部&…

linux 设置程序自启动

程序随系统开机自启动的方法有很多种&#xff0c; 这里介绍一种简单且常用的&#xff0c; 通过系统的systemd服务进行自启动。 第一步&#xff1a; 新建一个.service文件 sudo vim /etc/systemd/system/myservice.service[Unit] DescriptionMy Service #Afternetwork.target[…

【鸿蒙】稍微理解一下Stage模型

鸿蒙的Stage模型是HarmonyOS多端统一的应用开发框架中的一个核心概念&#xff0c;用于描述应用的界面层次结构和组件之间的关系。下面将详细解析Stage模型的主要组成部分和特点&#xff1a; 模型组成&#xff1a; UIAbility组件&#xff1a;这是应用中负责绘制用户界面的组件&a…

LeetCode:经典题之206、92 题解及延伸

系列目录 88.合并两个有序数组 52.螺旋数组 567.字符串的排列 643.子数组最大平均数 150.逆波兰表达式 61.旋转链表 160.相交链表 83.删除排序链表中的重复元素 389.找不同 1491.去掉最低工资和最高工资后的工资平均值 896.单调序列 206.反转链表 92.反转链表II 141.环形链表 …

【应用开发二】GPIO操控(输出、输入、中断)

1 操控GPIO方式 控制目录&#xff1a;/sys/class/gpio /sys/class/gpio目录下文件如下图所示&#xff1a; 1.1 gpiochipX目录 功能&#xff1a;当前SoC所包含的所有GPIO控制器 i.mx6ull一共包含5个GPIO控制器&#xff0c;分别为GPIO1~5分别对应gpiochip0、gpiochip32、gpi…

视频共享融合赋能平台LntonCVS安防监控平台现场方案实现和应用场景

LntonCVS国标视频融合云平台采用端-边-云一体化架构&#xff0c;部署简单灵活&#xff0c;功能多样化。支持多协议&#xff08;GB28181/RTSP/Onvif/海康SDK/Ehome/大华SDK/RTMP推流等&#xff09;和多类型设备接入&#xff08;IPC/NVR/监控平台&#xff09;。主要功能包括视频直…

【2024大语言模型必知】做RAG时为什么要使用滑动窗口?句子窗口检索(Sentence Window Retrieval)是什么?

目录 1. 传统的向量检索方法&#xff0c;使用整个文档检索&#xff0c;为什么不行&#xff1f; 2.句子滑动窗口检索&#xff08;Sentence Window Retrieval&#xff09;工作原理 3.句子滑动窗口检索&#xff08;Sentence Window Retrieval&#xff09;的优点 1. 传统的向量检…

区块链的技术架构:节点、网络和数据结构

区块链技术听起来很高大上&#xff0c;但其实它的核心架构并不难理解。今天我们就用一些简单的例子和有趣的比喻&#xff0c;来聊聊区块链的技术架构&#xff1a;节点、网络和数据结构。 节点&#xff1a;区块链的“细胞” 想象一下&#xff0c;区块链就像是一个大型的组织&a…

001 SpringMVC介绍

文章目录 基础概念介绍BS和CS开发架构应用系统三层架构MVC设计模式 SpringMVC介绍SpringMVC是什么SpringMVC与Spring的联系为什么要学习SpringMVC 六大组件介绍六大组件(MVC组件其他三大组件)说明 基础概念介绍 BS和CS开发架构 一种是C/S架构&#xff0c;也就是客户端/服务器…

启动Redis服务器

名人说&#xff1a;一点浩然气&#xff0c;千里快哉风。 ——苏轼 创作者&#xff1a;Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 目录 一、在 Linux 或 macOS 上启动 Redis二、在 Windows 上启动 Redis三、配置 Redis 为服务启动&…

ExVideo: 提升5倍性能-用于视频合成模型的新型后调谐方法

标题&#xff1a;ExVideo: Extending Video Diffusion Models via Parameter-Efficient Post-Tuning作者: Zhongjie Duan; Wenmeng Zhou; Cen Chen; Yaliang Li; Weining QianDOI: 10.48550/arXiv.2406.14130摘要: Recently, advancements in video synthesis have attracted s…

【IJCAI2024】LeMeViT: Efficient Vision Transformer with Learnable Meta Tokens

【IJCAI2024】LeMeViT: Efficient Vision Transformer with Learnable Meta Tokens for Remote Sensing Image Interpretation 论文&#xff1a;https://arxiv.org/abs/2405.09789 代码&#xff1a;https://github.com/ViTAE-Transformer/LeMeViT 由于相邻像素和图像块之间的高…

【2024年更新】ZF关注度指数大合集(包含8类数据)

数据简介&#xff1a;共包含8类数据 1. 地方ZF环境关注度指数&#xff1a;2007-2021 2. 地方ZF数字关注度指数&#xff1a;1999-2021 3. 省级ZF数字关注度指数&#xff1a;2001-2024 4. 农业新质生产力ZF关注度指数&#xff1a;2001-2024 5. 新质生产力ZF关注度指数&#…

c语言入门

c语言入门 C语言一经出现就以其功能丰富、表达能力强、灵活方便、应用面广等特点迅速在全世界普及和推广。C语言不但执行效率高而且可移植性好&#xff0c;可以用来开发应用软件、驱动、操作系统等。C语言也是其它众多高级语言的鼻祖语言&#xff0c;所以说学习C语言是进入编程…

关于怎么将wireshark抓包视频流转为视频播放出来

0.安装wireshark 安装PotPlayer 1.将以下两个插件放入 C:\Program Files\Wireshark\plugins 目录中 2.筛选视频流数据包&#xff0c;右键Decode As… 改为RTP 或者 右键->follow&#xff08;追踪流&#xff09;->UDP stream 然后叉掉弹窗 3.选择菜单Edit->Prefe…

js取数组最大值之Math.max、Math.max.apply

js取数组最大值之Math.max、Math.max.apply Math.maxMath.max.applyapply()第一个参数为什么可以是null 最小值同理 Math.max Math.max(n1,n2,n3,…,nX) 支持传递多个参数&#xff0c;带有较大的值的那个数 Math.max(2,5,3,6,2,4,2,15,9,6,0,1)Math.max.apply apply() 语法&a…

shell编程实战

1.1 shell脚本编程的步骤 需求分析&#xff1a;确定功能 命令测试&#xff1a;确定脚本需要的关键命令 编辑脚本 测试脚本 1.2 操作 1.2.1 实验一 1.需求描述 (1)统计网络中的服务器的mac 注&#xff1a;ARP&#xff0c;地址解析协议 注&#xff1a; (2)检查哪些主机开…