1. 求子串定位函数 :index(String S , String T ,int pos)
(1) 介绍
参数介绍 :S 为主串 ,T 为模式串 ,pos 为主串匹配算法遍起始位置 , 如果模式串存在于 主串 S 中的返回索引起始位置 , 否则返回 -1.
(2) 时间复杂度
O(n+m)n,m 分别为主串与模式串的长度
(3) 代码算法
/**
* 返回模式串在主串第一次出现的位置
*
* @param S 主串
* @param T 模式串
* @param pos 主串起始位
* @return 模式串在主串中的起始位置 , 不存在则返回 - 1
*/
public int index(String S,String T, int pos) {
// 起始位置需小于主串的长度
if (pos >=S.length()) {
return -1;
}
int i = pos; int j = 0; // 模式串 T 下标记录符
// 匹配开始
while (i < S.length()&& j < T.length()) {
// 循环执行条件为 i,j 不超过主串与模式串数组长度
if (S.charAt(i) ==T.charAt(j)) {
i++;j++; // 如果匹配完成则 j=T.length() 跳出循环
} else {
// 指针后移
i = i - j + 1;j = 0;
}
}
if (j >=T.length())
return i - j;
else
return -1;
}
(4) 思考
如果主串为 aaaaaaaaaaaaaaa...aaaaaaaaaaaaaab, 模式串为 aaaaaaab, 则模式串中有 7 个 a 而主串有 n 个 a, 则每趟比较都出现最后一个字符不相等的情况 , 则指针 i 需要回 溯 n 次 , 效率很低 这时出现了算法时间复杂度最坏的情况 O(n*m), 后面将介绍另外 一种更好的匹配算法 .
2. 求子串定位函数 :KMP 算法
(1) 介绍
上述算法最后的思考题可以看出 , 大量的回溯导致了匹配算法的性能被降低了 , 为了 解决这个问题 , 由可 knuth( 克努特 ),morris(莫里斯 ),pratt( 布拉特 ) 同时提出的新算法 解决 , 后人称为 KMP 算法 , 此算法的特点就是在匹配过程中 , 主串指针不会回溯 , 采用 模式串右移 (即遍历模式串当前指针所指的元素的左边部分 ) 的方法 , 以提高算法的 整体效率 .
(2) 时间复杂度
O(n+m)n 为主串的长度 ,m 为模式串长度 ,KMP 算法能确保在 O(n+m) 的数量级上完成 串的模式匹配操作 .
(3) 代码算法
/**
* KMP 算法
*
* @param S 主串
* @param T 模式串
* @param pos 主串起始位
* @return 模式串在主串中的起始位置 , 不存在则返回 - 1
*/
public int index_KMP(StringS, String T, int pos) {
// 起始位置需小于主串的长度
if (pos >=S.length()) {
return -1;
}
int i = pos;
int j = 0; // 模式串 T 下标记录符
while (i < S.length()&& j < T.length()) {
if (j == -1 ||S.charAt(i) == T.charAt(j)) {
// j == -1 表示主串下标为 i 时模式串没有与之相等的字符
// 所以跳过次字符 ,i++, 并且模式串指向第一个字符从新匹配 ,j++
i++;
j++;
} else {
// 如果当前主串下标对应字符与模式串当前字符不匹配
// 主串不回溯 , 模式串右移 , 即向前遍历模式串的字符查找与当前主 串字符相匹 配的字符
// 如果没有找到则返回 -1
j = next(j,T, S.charAt(i));
}
}
if (j == T.length())
return i - j;
else
return -1;
}
/**
* 返回与主串指定字符相等的模式串字符位置
*
* @param j
* @param T
* @param s
* @return
*/
public static int next( int j, String T, char s) {
j -= 1; // 模式串从当前下标位置后一位开始查询与主串指针所指向的元素相 等元素的 位置
while (j >= 0) {
if (T.charAt(j) == s){
break ;
}
j--;
}
return j;
}
3. 两种算法比较
(1) 测试数据
StringBuffer strB = new StringBuffer();
for ( int i = 0; i < 10000000; i++) {
strB.append( "0" );
}
主串 :strB
模式串 :"000000001"
(2) 算法代码改进
在两个比较算法中 , 每进行一次回溯或者移位 , 标记符会 +1, 以此查看移动比较次数 .
(3) 主函数
public static void main(Stringargs[]) throws Exception {
// 计算时间差变量定义
Date beginDate;
Date endDate;
long between;
SimpleDateFormat sdf= new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" );
MyString ms = new MyString();
StringBuffer strB = new StringBuffer();
for ( int i = 0; i <10000000; i++) {
strB.append( "0" );
}
strB.append( "1" );
/* 此时 strB="00000000000...00000001"*/
beginDate = new Date();
ms.index(strB.toString(), "00000001" , 0);
endDate = new Date();
beginDate =sdf.parse(sdf.format(beginDate).toString());
endDate =sdf.parse(sdf.format(endDate).toString());
between =(endDate.getTime() - beginDate.getTime());
System. out .println( " 基础算法时间差 :" + between);
beginDate = new Date();
ms.index_KMP(strB.toString(), "00000001" , 0);
endDate = new Date();
beginDate =sdf.parse(sdf.format(beginDate).toString());
endDate =sdf.parse(sdf.format(endDate).toString());
between =(endDate.getTime() - beginDate.getTime());
System. out .println( " 改进后的 KMP 算法时间差 :" + between);
}
(4) 结果
基础算法比较次数 :289999813
基础算法时间差 :1000
KMP 算法比较次数 :29999995
改进后的 KMP 算法时间差 :0
(5) 结果分析
因为 KMP 算法所用时在毫秒级之内 , 所以显示为 0, 在比较次数上 , 基础算法所用时整 整多了一个数量级 , 也证明了 KMP 算法的确能很好的提升匹配算法的效率 .
4.JDK-String.indexOf(Str) 原码分析
相关推荐
带通配符的字符串匹配算法则是这个领域的延伸,它允许在模式字符串中包含特殊字符,如星号(*)或问号(?),以表示任意字符或单个任意字符。这种算法使得搜索更加灵活,可以适应更复杂的查询需求。 **通配符的含义** -...
### 串匹配算法详解 #### 一、串匹配算法概览 串匹配算法是指在文本字符串(正文)中查找特定的子字符串(模式)的过程。这类算法广泛应用于文本搜索、数据压缩、生物信息学等领域。根据给定的描述,本文将深入...
### 字符串匹配算法之Horspool算法:深入解析与应用 #### 引言 在计算机科学领域,字符串匹配是一项核心任务,广泛应用于文本编辑、数据检索、模式识别等多个场景。传统的简单匹配算法如逐一比较法往往在面对大...
**KMP字符串匹配算法详解** KMP(Knuth-Morris-Pratt)字符串匹配算法是由D.E. Knuth、V.J. Morris和J.H. Pratt三位学者于1977年提出的,它是一种高效的字符串搜索算法,主要用于在一个主串(text)中查找是否存在...
在C语言中,实现字符串匹配算法通常涉及到对字符数组的操作和逻辑控制结构。本篇文章将详细探讨四种常见的字符串匹配算法:平凡算法(SimpleSM)、KMP算法(KMPSM)、BM算法(bmSM)以及RK算法(rkSM),并分析它们...
在这个主题中,我们将探讨三种经典的字符串匹配算法:穷举法、KMP(Knuth-Morris-Pratt)算法和BM(Boyer-Moore)算法。 1. **穷举法**:也称为朴素匹配算法,是最直观的字符串匹配方法。它通过比较主串中的每个...
这里我们将深入探讨几种常见的字符串匹配算法,包括Brute Force算法、KMP算法、Horspool算法以及Boyer-Moore算法。 1. **Brute Force算法**:这是最直观的字符串匹配方法,也被称为简单匹配。它将模式串与匹配串...
### 改进的多模式字符串匹配算法 #### 摘要与背景介绍 本文提出了一种改进的多模式字符串匹配算法,旨在优化经典的AC(Aho-Corasick)多模式字符串匹配算法,并融合了BMH(Boyer-Moore-Horspool)算法的优势。这一...
朴素串匹配算法过程示意 朴素串匹配算法过程示意
《多模式字符串匹配算法——AC_BM算法的深度解析与实现》 字符串匹配算法是计算机科学中的一个重要领域,尤其在文本处理、搜索引擎、数据挖掘等领域有着广泛应用。其中,AC_BM算法,即Aho-Corasick算法结合Boyer-...
串匹配算法是计算机科学中的核心问题,特别是在文本处理、图像分析、信息检索、自然语言处理和生物信息学等领域,有着广泛的应用。串匹配的主要任务是在一个给定的文本字符串(Text String)中寻找一个模式字符串...
### 字符串匹配算法小集解析 #### 一、引言 本文档提供了一系列共35种不同的字符串匹配算法,这些算法在英文环境下被广泛讨论和应用。通过对这些算法进行详细的解析,我们可以更好地理解每种算法的特点、应用场景...
### 入侵检测技术中一种改进的字符串匹配算法的研究 #### 概述 随着网络环境的日益复杂化,网络攻击事件频繁发生,如何有效监测和响应这些潜在威胁成为了网络安全领域的重要课题。入侵检测系统(IDS)作为网络安全...
本主题将深入探讨串(字符串)的数据结构及其相关算法,特别是顺序存储和朴素串匹配算法。 首先,让我们从串的顺序存储开始。在计算机科学中,串是由字符组成的序列,可以看作是一种特殊类型的数据结构。顺序存储是...
**字符串匹配算法-BM算法的实现代码** 在计算机科学领域,字符串匹配算法是寻找一个字符串(称为模式)在另一个较大的字符串(称为文本)中的过程。BM(Boyer-Moore)算法是一种高效的字符串搜索算法,由Robert S. ...
### 字符串匹配算法详解 #### 一、引言 字符串匹配算法是在计算机科学领域内极为重要的基础之一,广泛应用于诸如文本处理、生物信息学、数据挖掘等多个领域。本文将从简单的蛮力算法出发,逐步深入到较为高效的...
一般而言文本就是要编辑的文档,而模式字符串往往由用户来指定,高效的字符串匹配 算法可以提高程序的响应性能,当然字符串匹配算法的应用远远不止于此,例如在生物计算科学中查找特定的DNA序列,也是字符串匹配算法...
### 多串匹配算法及其启示 #### 一、问题背景与描述 在计算机科学领域,字符串处理技术一直是研究的重点之一,特别是在信息检索、生物信息学等领域有着广泛的应用。多串匹配问题是字符串处理中的一个重要分支,它...