• 数据结构之KMP算法next数组


      我们要找到一个短字符串(模式串)在另一个长字符串(原始串)中的起始位置,也就是模式匹配,最关键的是找到next数组。最简单的算法就是用双层循环来解决,但是这种算法效率低,kmp算法是针对模式串自身的特点,当失配时,能够利用next数组得到的信息直接跳过不可能匹配成功的位置字符。例如模式字符串“ababaaaba”,假设当匹配到第6个字符“a”发生错误,传统方法是原始字符串往后移动一个,但是原始串显然第2个字符是b(因为之前匹配过了),不可能是模式串的起始字符,而next会发现从原始串的第1个字符开始的“aba”和第3个字符开始的“aba”是一样的,所以直接将模式串的第1个字符和原始串的往后移动2个的字符比较,而此时直接用模式串第4个字符与之前原始串中失配的字符比也就是说模式串中第6个位置和第4个位置的字符位置等价,你失配了我来,因为他们前面有相同的串,而且其中一个是从模式串的起始位置开始的,这也就是next数组的定义。

      说的这么详细是因为考研期间这个部分非常难,我本人也是用了几天才参透这里面的原理,毕竟是非常著名的算法,不是背上来代码那么简单。​​

      字符串​一般是从编号1开始,第0个位置存放长度,简单起见下面的代码简化表示。

    #define _CRT_SECURE_NO_DEPRECATE//vs编译器编译c语言需要加此条语句
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    void get_next(int *next, char *Array,int len) /*求NEXT[]的值*/
    {
    	int i = 1, j = 0;  //如果字符串不是从编号1开始,则初始化i=0,j=-1,i<len-1
    	next[1] = 0;//初始化第一个字符的next值为0
    	while (i < len)//整个过程中i变量一遍走过,而j变量可能会回溯,i一直在j后面
    	{
    		if (j == 0 || Array[i] ==Array[j])//起始或者字符有重复,那么下一个位置i++和j++的位置等价,
    		{
    			i++;
    			j++;
    			if (Array[i] == Array[j])
                   next[i] = next[j];   //优化找到最开始的等价位,等价位的等价位
    			else
    				next[i] = j;
    		}
    		else
    			j = next[j];  //回溯,正是利用了next数组本身的回溯的功能
    	}
    }
    int main()
    {
    	char A[] = "0ababaaaba";//为了使得字符数据从编号1开始
    	int next[sizeof(A)-1] = { 0 };//初始化
    	int len = sizeof(A)-1;
    	get_next(next, A,len);
    	for (int i = 1; i < len;i++)
    		printf("%d ",next[i]);
    	system("pause");//vs运行需要加此条代码
    	return 0;
    }
    

      

    运行结果:​若为未改进的算法,模式串“ababaaaba”的next运行结果为

      0 1 1 2 3 4 2 2 3,

      改进算法运行结果为0 1 0 1 0 4 2 1 0。

      考试题也有可能不考代码,我的经验是先根据算法写出为改进的,然后从头开始对应的字符一样就改为前面那个字符的next值,以此类推。​

  • 相关阅读:
    node-sass安装失败问题
    通过JS下载 or 唤起App
    获取地址栏参数
    JS获取浏览器可视区域的尺寸
    Pyhton2.x 和Python3.x
    导入一个AndroidStudio工程作为一个Library Module
    win10 右键菜单添加Git Hash Here
    CTRL-Space always toggles Chinese IME (Windows 7、10)
    DOM解析XML报错:Content is not allowed in prolog
    重复安装相同包名APK出现的问题。
  • 原文地址:https://www.cnblogs.com/BetterThanEver_Victor/p/5145273.html
Copyright © 2020-2023  润新知