字符串匹配之PabinKarp(模式匹配)
一、什么是字符串匹配呢?
给定一个母串,再给定一个子串,要在母串中找是否有与子串对应的字符串
例如:母串S:ABABAC
子串P:BAB
方法一:一般做法(时间复杂度很高)
利用指针Si和指针Pj作比较
如果它们相同就i+1,j+1;如果到某一个地方不同,称为失配。
当出现失配,把i退回之前标记的位置向后移动一个i+1的位置,j变为0回到起始点。一直重复上面操作。
直到i找到对的位置记为k,k位置和P0作比较,后面都符合匹配,两个指针一直向后移动,做++操作,当连续累计匹配个数等于P的长度时候,称为找到合适位置,返回m.
原因:假设S的长度为m,需要将母串S的字符都要作为起点,需要做m次匹配
假设P的长度为n
则它们的时间复杂度为0(n×m)
方法二:哈希法RabinKarp
hash-----滚动hash
思路:在子串P把字符串求出一个整数值,例如3个字符求出一个值;任意多个字符按一定顺序排列(字符序列,字符串)都可以求出一个值。这个值称为哈希值。
对S采用同样的算法,从起点开始,对每3字符序列的哈希值求出来。
算出来之后比对哈希值。
在母串S中求值只需要m次
在子串P中求值需要n次
先对P求哈希,o(n)
对S求哈希,o(m)
此时它们的时间复杂度仍为o(m×n),并未降低
求哈希hash
把若干个字符按进制的方法做一个转换,假设一个种子值为31进制,
在P子串中
C ^0 × 31^2+ C^1 ×31^1+C2
这样代码不好写,改进
((0+C0)×31+C1)×31+C2
什么是滚动hash,我求出第一个长度为n的子串的hash值,根据hash计算的特点,算第二个子串的hash值得时候不用再算,用第一个hash值×C(种子的值)+新增的字符元素值-第一个元素的值
在算每n个(在这道题里面是3个)子串hash值的时候,将它们组成一个数组。
先求P子串的hash值,再求S母串的hash,m次
有hash数组之后,把母串S数组扫描一遍,匹配与子串P相同hash值时m次
o(2m+n)
再这个题目中每三个元素的hash值,一开始需要三次,后面只需要1次
滚动hash:时间复杂度0(n+m)
- 代码:
package rabinkarp;
import org.Lanqiao.rabinkarp.elementary.NExponent;
/*滚动hash法* 对目标字符串按d进制求值,mod h取余作为其hash* 对原串,依次求出m个字符的hash,保存在数组中(滚动计算)* 匹配时,只需比对目标串的hash值和预存的原串的hash值表*/
/*S:母串 P:子串*/
public class Rabinkarp {public static void main(String[] args) {String s="ABABABA";String p="ABA";match(p,s);}private static void match(String p,String s) {long hash_p =hash(p); //p的hash值int p_len=p.length();for(int i=0;i+p_len<=s.length();i++) {long hash_i=hash(s.substring(i,i+p_len));//i为起点,长度为plen的子串的hash值if(hash_i==hash_p) {System.out.println("match:"+i);}}long[] hashOfS=hash(s,p.length());match(hash_p,hashOfS);}
private static void match(long hash_p,long[] hash_s) {for(int i=0;i<hash_s.length;i++) {if(hash_s[i]==hash_p) {System.out.println("match:"+i);}}
}
final static long seed=31;
//n是子串的长度
//用滚动hash法求出s中长度为n的每个子串的hash,组成一个hash数组
static long[] hash(final String s,final int n) {long[] res=new long[s.length()-n+1];//前面m个字符的hash值res[0]=hash(substring(0,n));for(int i=n;i<s.length();i++) {char newChar=s.charAt(i);char oldchar=s.charAt(i-n);//前n个字符的hash值*seed-前n字符的第一个字符元素*seed的n次方long v=(res[i-n]*seed+newChar-NExponent.ex2(seed,n)*oldchar)%Long.MAX_VALUE;res[i-n+1]=v;}return res;
}
private static String substring(int i, int n) {// TODO Auto-generated method stubreturn null;
}
/*使用100000个不同字符串产生的冲突数,大概在0-3波动,使用100百万不同的字符串,冲突数大概在100+范围波动*/
static long hash(String str) {long h=0;for(int i=0;i!=str.length();i++) {h=seed*h+str.charAt(i);}return h%Long.MAX_VALUE;}
}
字符串匹配之PabinKarp(模式匹配)相关推荐
- 字符串匹配(多模式匹配篇)
字符串匹配(多模式匹配篇) 摘要: 问题的提出:众所周知,KMP算法在O(n)的时间中solve单模式串匹配问题.但怎样solve多模式串匹配问题呢? Solve:本文用简要记叙了使用trie树,tr ...
- 字符串匹配和KMP模式匹配(没太学懂,暂时不写)
//字符串匹配 int stringMatching(string longstr, string smallstr){int lLen = longstr.size(), sLen = smalls ...
- 分享一下字符串匹配BM算法学习心得。
字符串匹配BM(Boyer-Moore)算法学习心得 BM算法 是 Boyer-Moore算法 的缩写,是一种基于后缀比较的模式串匹配算法.BM算法在最坏情况下可以做到线性的,平均情况下是亚线性的(即 ...
- 【NLP】darmatch: 一个非常高效的多模式字符串匹配工具
darmatch 是一个非常高效的字符串匹配工具,支持正向/反向最大匹配分词和多模式字符串精确匹配: 仅包含头文件 (header-only) 基于双数组字典树 (double-array trie) ...
- java中字符串的精确匹配_Java最佳实践–字符串性能和精确字符串匹配
java中字符串的精确匹配 在使用Java编程语言时,我们将继续讨论与建议的实践有关的系列文章,我们将讨论String性能调优. 我们将专注于如何有效地处理字符串创建, 字符串更改和字符串匹配操作. ...
- Java最佳实践–字符串性能和精确字符串匹配
在使用Java编程语言时,我们将继续讨论与建议的实践有关的系列文章,我们将讨论String性能调优. 我们将专注于如何有效地处理字符串创建, 字符串更改和字符串匹配操作. 此外,我们将提供我们自己的用 ...
- 字符串匹配(KMP 算法 含代码)
主要是针对字符串的匹配算法进行解说 有关字符串的基本知识 传统的串匹配法 模式匹配的一种改进算法KMP算法 网上一比較易懂的解说 小样例 1计算next 2计算nextval 代码 有关字符串的基本知 ...
- java 字符串匹配_多模字符串匹配算法原理及Java实现代码
多模字符串匹配算法在这里指的是在一个字符串中寻找多个模式字符字串的问题.一般来说,给出一个长字符串和很多短模式字符串,如何最快最省的求出哪些模式字符串出现在长字符串中是我们所要思考的.该算法广泛应用于 ...
- 字符串匹配:字符串中查找某子串
字符串匹配:字符串中查找某子串 需求 具体算法 常规方法 程序 KMP算法 程序 后续 需求 我们在平时的软件开发,尤其是嵌入式开发,字符串匹配是非常重要的一个算法.而目前常用的字符串匹配算法有很多, ...
最新文章
- java8 collect 类型转换_java8新特性之list转换
- 一个创业者的自我修养2019版
- mysql类 php100_PHP100中,制作自己的PHP.MYSQL类中:Access denied for user ''@'localhost' (using password: NO)...
- hibernate基于单表curd
- ARM中ROM,RAM,FLASH区别
- duration java_Java Duration类| ofDays()方法与示例
- this compilation unit is not on the build of a java project
- 【方案分享】2021年钟薛高营销策划方案.pptx(附下载链接)
- js 操作数组函数-自定义
- function传值传字符串,然后Ajax url传值的时候传这个装字符串的变量
- JSP程序设计课后习题答案
- 国内第三个双机场城市新机场试飞,6月正式投用
- PS图片删除需要计算机管理权限,电脑打开ps,显示没有管理员权限
- PS学习笔记6-选区工具
- 雷电模拟器+proxifier
- python爬虫时爬虫爬数据时出现“访问本页面,请开启JavaScript并刷新该页”
- 手把手教你用Python高仿一个任务管理器
- 3D MAX界面操作教程及渲染技巧
- 职场选择之大公司 VS 小公司
- 超级简单却又非常好吃的一顿饭——排骨汤
热门文章
- 5岁儿童自学python编程-适合6-16岁孩子学习的Python编程
- python软件下载3版本-Python 3.7.2和3.6.8版本发布下载,附更新说明
- python是什么-Python 简介
- python所有软件-如何在Python中列出所有已安装的软件包及其版本?
- python工资一般多少p-Python P值
- |ViaVoice(IBM语音识别输入系统)下载v9.1官方版 - 欧普软件下载
- 数字语音识别 - 源码下载|数值算法/人工智能|matlab例程|源代码 - 源码中国
- LeetCode 123买卖股票的时机 III
- matlab给hfss建模,HFSS-MATLAB联合建模
- java调用geckofx_Scala学习(三)数组相关操作