常用字符串匹配算法

一、BF匹配

BF算法中的BF是Brute Force的缩写,中文叫作暴力匹配算法,也叫朴素匹配算法。
BF算法的时间复杂度很高,是O(nm),但在实际的开发中,它却是一个比较常用的字符串匹配算法。
第一,实际的软件开发中,大部分情况下,模式串和主串的长度都不会太大。而且每次模式串与主串中的子串匹配的时候,当中途遇到不能匹配的字符的时候,就可以就停止了,不需要把m个字符都对比一下。所以,尽管理论上的最坏情况时间复杂度是O(n
m),但是,统计意义上,大部分情况下,算法执行效率要比这个高很多。
第二,朴素字符串匹配算法思想简单,代码实现也非常简单。简单意味着不容易出错,如果有bug也容易暴露和修复。在工程中,在满性性能要求的前提下,简单是首选。

public class BFMate {public static void main(String[] args) {BFMate("adjhkljabclkffkk","abc");}public static boolean BFMate(String mainStr,String modelStr) {int len = mainStr.length()-modelStr.length();for(int i=0;i<len;i++) {if(modelStr.equals(mainStr.substring(i, i+modelStr.length()))) {System.out.println("main=="+mainStr.substring(i, i+modelStr.length()));return true;}}return false;}}

二、BM匹配

BM(Boyer-Moore)算法。它是一种非常高效的字符串匹配算法。

BM算法核心思想是,利用模式串本身的特点,在模式串中某个字符与主串不能匹配的时候,将模式串往后多滑动几位,以此来减少不必要的字符比较,提高匹配的效率。BM算法构建的规则有两类,字符规则和好后缀规则。好后缀规则可以独立于坏字符规则使用。因为坏字符规则的实现比较耗内存,为了节省内存,我们可以只用好后缀规则来实现BM算法。

public class BMMate {private final int Size = 256;public void generateBC(char[] b,int m,int[] bc) {for(int i=0;i<Size;i++) {bc[i] = -1;//初始化bc}for(int i=0;i<=m;i++) {int ascii = (int)b[i];//计算b[i]的ASCII值bc[ascii] = i;//b[i]在bc中的位置}}//b表示模式串,m表示长度,suffix、prefix数组事先申请好了private static void generateGS(char[] b,int m,int[] suffix,boolean[] prefix) {for(int i=0;i<m;i++) {//初始化suffix[i] = -1;prefix[i] = false;}for(int i=0;i<m-1;i++) {//b[0,i]int j=i;int k=0;//公共后缀子串长度while(j>=0&&(b[j] == b[m-1-k])) {//与b[0,m-1]求公共后缀子串--j;++k;suffix[k]=j+1;//j+1表示公共后缀子串在b[0,i]中的起始下标System.out.println("i="+i+",j="+j);System.out.println("suffix"+k+"="+suffix[k]);}if(j==-1) {prefix[k] = true;//如果公共后缀子串也是模式串的前缀子串System.out.println("prefix"+k+"="+prefix[k]);}}}public int bm(char[] a,int n,char[] b,int m) {int [] bc = new int[Size];//记录模式串中每个字符最后出现的位置generateBC(b,m,bc);//构建坏字符哈希表int[] suffix = new int[m];boolean[] prefix = new boolean[m];generateGS(b,m,suffix,prefix);int i=0;//表示主串与模式串第一个字符对齐while(i<n-m) {int j=0;for(j=m-1;j>=0;j--) {//模式串从后往前匹配if(a[i+j] != b[j]) break;}if(j<=0) return i;//匹配成功,返回主串与模式串第一个匹配字符的位置int x = j-bc[(int)a[i+j]];int y = 0;if(j<m-1) {//如果有好后缀的话y = moveByGS(j,m,suffix,prefix);	}i = i+Math.max(x, y);}return -1;}//j表示坏字符对应的模式串中的字符下标;m表示模式串长度private int moveByGS(int j,int m,int[] suffix,boolean[] prefix) {int k=m-1-j;//好后缀长度if(suffix[k] != -1) {return j-suffix[k]+1;}for(int r = j+2;r<=m-1;++r) {if(prefix[m-r]==true) {return r;}}return m;}
}

三、Trie树

Trie树,也叫“字典树”。顾名思义,它是一个树形结构。它是一种专门处理字符串匹配的数据结构,用来解决在一组字符串集合中快速查找某个字符串的问题。
在这里插入图片描述

/*** 假设插入的数据只包含26个小写字母组成的单词* 将26个字母映射的一个长度26的数组中,下标0-25分别对应a-z* * 插入字符串时间复杂度 : O(n),n表示所有字符串的长度和* 查找字符串时间复杂度 : O(k),k表示要查找的字符串的长度* * Trie树不适合精确匹配查找,这种问题更适合用散列表或者红黑树来解决。* Trie树比较适合的是查找前缀匹配的字符串,类似实现搜索关键词的提示功能。*/
public class TrieTree {private TrieNode root = new TrieNode('/');//存储无意义字符串public class TrieNode {public char data;public TrieNode[] children = new TrieNode[26];public boolean isEndingChar;public TrieNode(char data) {this.data = data;}}//往Trie树中插入一个数据public void insert(char[] data) {TrieNode node = root;for(int i=0;i<data.length;i++) {if(node.children[data[i]-'a']==null) {node.children[data[i]-'a'] = new TrieNode(data[i]);}node = node.children[data[i]-'a'];}node.isEndingChar = true;}//在Trie树中查找一个数据public boolean find(char[] data) {TrieNode node = root;for(int i=0;i<data.length;i++) {if(node.children[data[i]-'a']==null) {return false;//不存在}node = node.children[data[i]-'a'];}if(node.isEndingChar==false) {return false;//不是完全匹配}else {return true;//完全匹配}}
}
public class TestTrieTree {public static void main(String[] args) {TrieTree tree = new TrieTree();//how,hi,her,hello,so,seetree.insert(new char[] {'h','o','w'});tree.insert(new char[] {'h','i'});tree.insert(new char[] {'h','e','r'});tree.insert(new char[] {'h','e','l','l','o'});tree.insert(new char[] {'s','o'});tree.insert(new char[] {'s','e','e'});System.out.println(tree.find(new char[] {'h','i'}));System.out.println(tree.find(new char[] {'h','a'}));}
}

运行结果

true
false

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

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

相关文章

JVM——配置常用参数,GC调优策略

文章目录 JVM 配置常用参数Java内存区域常见配置参数概览堆参数回收器参数项目中常用配置常用组合 常用 GC 调优策略GC 调优原则GC 调优目的GC 调优策略 JVM 配置常用参数 Java内存区域常见配置参数概览堆参数&#xff1b;回收器参数&#xff1b;项目中常用配置&#xff1b;常…

【nodejs】用Node.js实现简单的壁纸网站爬虫

1. 简介 在这个博客中&#xff0c;我们将学习如何使用Node.js编写一个简单的爬虫来从壁纸网站获取图片并将其下载到本地。我们将使用Axios和Cheerio库来处理HTTP请求和HTML解析。 2. 设置项目 首先&#xff0c;确保你已经安装了Node.js环境。然后&#xff0c;我们将创建一个…

cuOSD(CUDA On-Screen Display Library)库的学习

目录 前言1. cuOSD1.1 Description1.2 Getting started1.3 For Python Interface1.4 Demo1.5 Performance Table 2. cuOSD案例2.1 环境配置2.2 simple案例2.3 segment案例2.4 segment2案例2.5 polyline案例2.6 comp案例2.7 perf案例 3. cuOSD浅析3.1 simple_draw函数 4. 补充知…

小程序中display:flex和v-show,v-show不生效,uni-app

小程序中display:flex和v-show&#xff0c;v-show不生效、、 解决方案&#xff1a; display&#xff1a;flex样式的优先级高于了v-show &#xff0c;v-show其实就是display&#xff1a;none&#xff0c;display&#xff1a;flex优先级高于display&#xff1a;none。 使用 :s…

【系统工具】开源服务器监控工具WGCLOUD初体验

经常看到服务器上传下载流量一直在跑&#xff0c;也不知道是啥软件在偷偷联网~~~官网地址&#xff1a;www.wgstart.com&#xff0c;个人使用是免费的。 WGCLOUD官网介绍 "WGCLOUD支持主机各种指标监测&#xff08;cpu使用率&#xff0c;cpu温度&#xff0c;内存使用率&am…

了解生成对抗网络 (GAN)

一、介绍 Yann LeCun将其描述为“过去10年来机器学习中最有趣的想法”。当然&#xff0c;来自深度学习领域如此杰出的研究人员的赞美总是对我们谈论的主题的一个很好的广告&#xff01;事实上&#xff0c;生成对抗网络&#xff08;简称GAN&#xff09;自2014年由Ian J. Goodfel…

K8s学习笔记1

一、课程介绍&#xff1a; 1、背景&#xff1a; 1&#xff09;从基础设备主机化向容器化转换。 2&#xff09;从人肉式运维工作模式向自动化运维模式转换。 3&#xff09;从自动化运维体系向全体系智能化运维模式转换。 2、课程目标人群: 1&#xff09;掌握Linux操作系统基…

【数据分享】2006-2021年我国城市级别的节约用水相关指标(免费获取\20多项指标)

《中国城市建设统计年鉴》中细致地统计了我国城市市政公用设施建设与发展情况&#xff0c;在之前的文章中&#xff0c;我们分享过基于2006-2021年《中国城市建设统计年鉴》整理的2006—2021年我国城市级别的市政设施水平相关指标、2006-2021年我国城市级别的各类建设用地面积数…

ES:一次分片设计问题导致的故障

### 现象&#xff1a; 1. 单节点CPU持续高 2.写入骤降 3.线程池队列积压&#xff0c;但没有reject 4.使用方没有记录日志 ### 排查 1.ES监控 只能看到相应的结果指标&#xff0c;无法反应出原因。 2.ES日志&#xff1a;大量日志打印相关异常&#xff08;routate等调用栈&a…

【仿写tomcat】六、解析xml文件配置端口、线程池核心参数

线程池改造 上一篇文章中我们用了Excutors创建了线程&#xff0c;这里我们将它改造成包含所有线程池核心参数的形式。 package com.tomcatServer.http;import java.util.concurrent.*;/*** 线程池跑龙套** author ez4sterben* date 2023/08/05*/ public class ThreadPool {pr…

微服务-Ribbon(负载均衡)

负载均衡的面对多个相同的服务的时候&#xff0c;我们选择一定的策略去选择一个服务进行 负载均衡流程 Ribbon结构组成 负载均衡策略 RoundRobinRule&#xff1a;简单的轮询服务列表来选择服务器AvailabilityFilteringRule 对两种情况服务器进行忽略&#xff1a; 1.在默认情…

Elasticsearch 处理地理信息

1、GeoHash ​ GeoHash是一种地理坐标编码系统&#xff0c;可以将地理位置按照一定的规则转换为字符串&#xff0c;以方便对地理位置信息建立空间索引。首先要明确的是&#xff0c;GeoHash代表的不是一个点而是一个区域。GeoHash具有两个显著的特点&#xff1a;一是通过改变 G…

赴日IT工作 平时接私活开发能去日本搞个IT公司吗?

有小伙伴问&#xff0c;我平时也会接一些私活开发项目&#xff0c;可以直接去日本搞一个IT公司吗&#xff1f;首先给出まとめ&#xff08;总结&#xff09;&#xff0c;如果你没有日本项目经验的话建议先找个会社试试&#xff0c;如果有项目经验的话&#xff0c;那你把前老板的…

PHP入门基础教程 - 专栏导读

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;全栈领域新星创作者✌&#xff0c;CSDN博客专家&#xff0c;阿里云社区专家博主&#xff0c;2023年6月CSDN上海赛道top4。 &#x1f3c6;数年电商行业从业经验&#xff0c;历任核心研发工程师&#xff0c;项目技术负责…

人工智能引领图文扫描新趋势

1. 背景和影响 近日&#xff0c;中国大学生服务外包创新创业大赛决赛在江南大学圆满落幕。为满足现代服务产业企业的现实需求&#xff0c;本次竞赛内容设计充分聚焦企业发展中所面临的技术、管理等现实问题&#xff0c;与产业的结合度更紧密&#xff0c;智能文字识别技术是大赛…

spad芯片学习总结

一、时间相关单光子计数法TCSPC(Time correlated single photon counting) 1> 如果spad接收用单次发射、峰值检测会怎么样 首先spad是概率性触发的器件&#xff0c;探测到的概率远小于1&#xff0c;而且不仅接收信号的光子可以触发&#xff0c;环境光噪声一样会被spad接收到…

Flink 数据集成服务在小红书的降本增效实践

摘要&#xff1a;本文整理自实时引擎研发工程师袁奎&#xff0c;在 Flink Forward Asia 2022 数据集成专场的分享。本篇内容主要分为四个部分&#xff1a; 小红书实时服务降本增效背景Flink 与在离线混部实践实践过程中遇到的问题及解决方案未来展望 点击查看原文视频 & 演…

Selenium的基本使用

文章目录 引入一.选择元素的基本方法1.根据id 选择元素2.根据 class属性选择元素当元素有 多个class类型 时 3.根据 tag名 选择元素4.通过WebElement对象选择元素5.find_element 和 find_elements 的区别 二.等待界面元素出现1.隐式等待2.显示等待 三.操控元素的基本方法1.点击…

基于springboot+vue的武汉旅游网(前后端分离)

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战 主要内容&#xff1a;毕业设计(Javaweb项目|小程序等)、简历模板、学习资料、面试题库、技术咨询 文末联系获取 项目介绍…

mysql知识点+面试总结

目录 1 mysql介绍 2 数据库常见语法 3 数据库表的常见语法 4 其他常见语法&#xff08;日期&#xff0c;查询表字段&#xff09; 5 JDBC开发步骤 6 索引 6.1 索引常见语法 7 常见面试总结 8 java代码搭建监控页面 1 mysql介绍 数据库&#xff1a;存储在硬盘上的文件系统…