Java数据结构-串及其应用-KMP模式匹配算法

串(string)是由零个或多个宇符组成的有限序列,又名叫字符串。

定义的解释:

??串中的字符数目n称为串的长度,定义中谈到“有限”是指长度n是一个有限的数值。

??零个字符的串称为空串(null string),它的长度为零,可以直接用两双引号一表示,也可以用希腊Φ字母来表示。

??所谓的序列,说明串的相邻字符之间具有前驱和后继的关系。

下面是串的一些概念性东西:

??空格串,是只包含空格的串。注意它与空串的区别,空格串是有内容有长度的,而且可以不止一个空格。

??子串与主串,串中任意个数的连续字符组成的子序列称为该串的子串,相应地,包含子串的串称为主串。子串在主串中的位置就是子串的第一个字符在主串中的序号。

??串的比较是通过组成串的字符之间的编码来进行的,而字符的编码指的是字符在对应字符集中的序号。比较两个串是否相等,必须是它们串的长度以及它们各个对应位置的字符都相等时,才算是相等。

串与线性表的比较

??两者的逻辑结构比较相似,不同的是串针对的是字符集(即串中的元素都是字符)。

??线性表更关注的是单个元素的操作,比如査找一个元素,插入或删除一个元素,但串中更多的是査找子串位置、得到指定位置子串、替换子串等操作。

??串的顺序存储结构是用一组地址连续的存储单元来存储串中的字符序列的。按照预定义的大小,为每个定义的串变量分配一个固定长度的存储区。一般是用定长数组来定义。

注意:

??串的连接操作,需要注意串长问题,可能遇到的问题就是两个串连接后会不会溢出,所以需要进行截断操作。

查找子串在主串中的位置,操作如下:

?1. 设i用于主串s1中当前位置下标值,j用于子串sub中当前位置下标值。

?2. 首先我们比较s1[1]与sub[1],如果相同的话,可能子串就开始了。

?3. 如果不相等,那么子串仍然是从sub[1]开始,而主串s1则以s1[2]与其比较。

?4. 如果连续出现子串长度次或以上匹配,那么就找到子串了,此时的j必然大于子串长度sub[0]。

KMP模式匹配算法:

??这个东西有些难懂,下面是我的学习的时候的一些经验,希望对大家有所帮助。

KMP模式匹配算法,不懂的话建议去鱼C看视频:http://study.163.com/course/courseMain.htm?courseId=468002,讲的很不错,很详细;

然后对于前后缀视频里面讲的还不是很详细清楚,不好理解的话可以去看阮一峰的这篇文章http://www.ruanyifeng.com/blog/2013/05/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm.html

还有两篇KMP推荐:

从头到尾彻底理解KMP(2014年8月22日版) - 结构之法 算法之道 - 博客频道 - CSDN.NET

http://blog.csdn.net/v_july_v/article/details/7041827

KMP算法学习初步 | 海虹不老阁——遥望北方的狼

http://haihongblog.com/archives/911.html

下面是我的Java实现版本:

package com.phn.string;
import java.util.Arrays;
/**
 * @author 潘海南
 * @Email [email protected]
 * @TODO 模式匹配算法
 * @date 2015年7月26日
 */
public class FOKMP {
    private static int[] getNext(String Str) {
        int[] next = new int[Str.length()];
        int i, j;
        i = 0;
        j = -1;
        next[0] = -1;
        while (i < Str.length() - 1) {
            if (j == -1 || Str.charAt(i) == Str.charAt(j)) {
                i++;
                j++;
                if (Str.charAt(i) != Str.charAt(j)) {
                    next[i] = j;
                } else {
                    next[i] = next[j];
                }
            } else {
                j = next[j];
            }
        }
        return next;
    }
    public static int indexKMP(String S, String T) {
        int i = 0;
        int j = 0;
        int[] next = getNext(T);
        System.out.println(Arrays.toString(next));
        while (i <= S.length() - 1 && j <= T.length() - 1) {
            if (j == -1 || S.charAt(i) == T.charAt(j)) {
                i++;
                j++;
            } else {
                j = next[j];
            }
        }
        if (j >= T.length())
            return i - T.length();
        return -1;
    }
}

版权声明:本文为博主原创文章,如需转载请注明出处并附上链接,谢谢。

时间: 2024-10-23 10:15:34

Java数据结构-串及其应用-KMP模式匹配算法的相关文章

数据结构--KMP模式匹配算法

今天,在看数据结构--串这一章节时,看到了KMP算法,相对较复杂些,在此单独做下整理. kmp算法是一种改进的字符串匹配算法,由D.E.Knuth与V.R.Pratt和J.H.Morris同时发现,因此人们称它为克努特--莫里斯--普拉特操作(简称KMP算法).KMP算法的关键是根据给定的模式串W1,m,定义一个next函数.next函数包含了模式串本身局部匹配的信息. 例子: 假如我们要比较两个字符串是否相等. 在T串中查找S串.我们用最笨的方法去想,就是将T串与S串中的每一个元素一一去匹配,

朴素和KMP模式匹配算法(Java)

朴素模式匹配算法 public class Test { //朴素模式匹配算法 public int Index(String s,String t,int pos){ int i = pos;//主串中第几个位置开始比较 int j = 0;//模式串中的第一个位置 while(i<s.length()&&j<t.length()){ if(s.charAt(i)==t.charAt(j)){ i++; j++; }else { i = i-j+1;//主串的下一个位置 j

改进版KMP模式匹配算法

背景 朴素匹配算法太低效了.冗余过多,已经比较过的,没必要重复:可以从比较结果中推导出来的,也没必要再重复. 核心 主串不回溯,变化要匹配的串的下一次比较的位置. 实现 两个函数,一个提供next数组,即存储要匹配的串的每一个元素匹配失败后,下一次要比较的位置的数组.另一个实现匹配. java代码 public class KMP {//获取next数组private int[] getNext(char[] t_char){int size = t_char.length;int next[]

详细解读KMP模式匹配算法

转载请注明出处:http://blog.csdn.net/fightlei/article/details/52712461 首先我们需要了解什么是模式匹配? 子串定位运算又称为模式匹配(Pattern Matching)或串匹配(String Matching).在串匹配中,一般将主串称为目标串,将子串称为模式串.本篇博客统一用S表示目标串,T表示模式串,将从目标串S中查找模式串T的过程称为模式匹配. 虽然我们的主角是KMP模式匹配算法,但我们还是要先从暴力匹配算法讲起,通过发现暴力匹配算法存

串-KMP模式匹配算法(nextval数组)

#include <stdio.h> #include <stdlib.h> #include <string.h> void get_next(char T[100],int *next); int Index_KMP(char S[100],char T[100],int pos); int main() { int n; char S[100],T[100]; gets(S); gets(T); n=Index_KMP(S,T,2); printf("%

串的两种模式匹配算法

模式匹配(模范匹配):子串在主串中的定位称为模式匹配或串匹配(字符串匹配) .模式匹配成功是指在主串S中能够找到模式串T,否则,称模式串T在主串S中不存在. 以下介绍两种常见的模式匹配算法: Brute-Force模式匹配算法 暴风算法,又称暴力算法. 算法的核心思想如下: 设S为目标串,T为模式串,且不妨设: S="s0s1s2-sn-1" , T="t0t1t2 -tm-1" 串的匹配实际上是对合法的位置0≦i≦n-m依次将目标串中的子串s[i-i+m-1]和模

数据结构(三)串---KMP模式匹配算法之获取next数组

(一)获取模式串T的next数组值 1.回顾 我们所知道的KMP算法next数组的作用 next[j]表示当前模式串T的j下标对目标串S的i值失配时,我们应该使用模式串的下标为next[j]接着去和目标串失配的i值进行匹配 而KMP算法的next求值函数 我们可以知道next除了j=1时,next[1]为0,其他情况都是比较前缀和后缀串的相似度(第三种情况是当相似度为0时,next值为0+1=1) next数组,是用来评判前后缀的相识度,而next值,则是等于相似度加一 2.思考 虽然我们知道是

数据结构(三)串---KMP模式匹配算法实现及优化

KMP算法实现 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <string.h> #define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0 #define MAXSIZE 40 typedef int ElemType; typedef int Status; //设置串的存储结构 typede

【数据结构和算法】:KMP模式匹配算法

Knuth-Morris-Pratt 字符串查找算法,简称为 "KMP算法",常用于在一个文本串S内查找一个模式串P 的出现位置,这个算法由Donald Knuth.Vaughan Pratt.James H. Morris三人于1977年联合发表,故取这3人的姓氏命名此算法.整个KMP的重点就在于当某一个字符与主串不匹配时,我们应该知道j指针要移动到哪里. 如图:C和D不匹配了,我们要把j移动到哪?显然是第1位,因为如下面蓝框所示,前面A已经匹配. 下面也如此: 可以把j指针移动到第