• KMP算法实现


    下面是一个C代码实现的KMP算法,算法最困难的地方是计算出next数组,里面记录了匹配字符串各个位上的值。这个值可以叫做“部分匹配值”或“覆盖率”。

    要理解KMP算法首先要知道“朴素字符串匹配”算法,就是从头到尾比较字符,如果相等就同时后移,如果不相等则源字符串的搜索位置后移一位,然后重新匹配一遍。KMP算法是对朴素匹配算法的改进,提出了一个很抽象的概念:部分匹配值。这个概念的意思是:在一个串里面前缀和后缀的最长的子串的长度。所以要理解KMP还要明白前缀和后缀指的是什么。

    建议仔细阅读阮一峰的 博客,写得图文并茂通俗易懂,或者图灵社区的 文章。少啰嗦,先看东西:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #define N 100
    
    void cal_next( char * str, int * next, int len )
    {
    	int i, j;
    
    	next[0] = 0;
    	for( i = 1; i < len; i++ )
    	{
    		j = next[ i - 1 ];
    		while( str[ j ] != str[ i ] &&  j > 0  )
    		{
    			j = j - 1;
    		}
    		if( str[ i ] == str[ j ] )
    		{
    			next[ i ] = j + 1;
    		}
    		else
    		{
    			next[ i ] = 0;
    		}
    	}
    }
    
    //返回值:模式字符串在源字符串第一次匹配的位置
    int KMP( char * str, int slen, char * ptr, int plen, int * next )
    {
    	int s_i = 0, p_i = 0;
    
    	while( s_i < slen && p_i < plen )
    	{
    		if( str[ s_i ] == ptr[ p_i ] )
    		{
    			s_i++;
    			p_i++;
    		}
    		else
    		{
    			if( p_i == 0 )
    			{
    				s_i++;
    			}
    			else
    			{
    				p_i = next[ p_i - 1 ];
    			}
    		}
    	}
    	return ( p_i == plen ) ? ( s_i - plen ) : -1;
    }
    
    int main()
    {
    	char str[ N ] = "ABCDAB ABCDABE ABCD";
    	char ptr[ N ] = "ABAABCABA";    //next: 0 0 1 1 2 0 1 2 3
    	//char ptr[N] = "ABCDAB";       //next: 0 0 0 0 1 2
    	//char ptr[N] = "AABCABCD";     //next: 0 1 0 0 1 0 0 0
    	int slen, plen;
    	int next[ N ];
    
    	slen = strlen( str );
    	plen = strlen( ptr );
    	cal_next( ptr, next, plen );
    	printf( "matched at: %d
    ", KMP( str, slen, ptr, plen, next ) );
    
    	return 0;
    }
    

    反思:
    由于朴素匹配算法在匹配失败的时候要从模式字符串的第一个字符重新开始,所以朴素匹配算法的时间复杂度是O(n*m)。而KMP有效的避免了重复搜索,所以时间复杂度是O(n+m)。

  • 相关阅读:
    silo 主机 报找不到 grain 实现错误的一个注意
    转:CRT注册
    Maven生命周期
    Maven学习笔记
    Java内存回收机制
    Selenium2.0和1.0的区别
    关于使用Selenium RC无法打开指定页面问题
    四儿子购买手册
    Objective-C 宏定义的收集
    设计模式:适配器模式
  • 原文地址:https://www.cnblogs.com/ingvar/p/5984725.html
Copyright © 2020-2023  润新知