zoukankan      html  css  js  c++  java
  • C实现KMA算法的小细节

    算法核心思想:

    利用已经部分配对的有效信息,让主串i指针不回溯,通过每次确定子串j指针的回溯位置,使得子串(模式串)重新匹配时尽量移动到最佳位置,以减少不必要的回溯。

    int* GetNext(char Str[])
    {
       int* Next = (int*)malloc(sizeof(int) * strlen(Str));
       if (Next == NULL) return NULL;	
       int j = 0;
       int k = -1;
       Next[0] = -1;
       while (j < strlen(Str) - 1)
       {
       	if (k == -1 || Str[k] == Str[j])
       	{
       		j++;
       		k++;
       		if (Str[k] == Str[j])
       		{
       			Next[j] = Next[k];
       		}
       		else
       		{
       			Next[j] = k;
       		}
       	}
       	else
       	{
       		k = Next[k];
       	}
       }
       return Next;
    }
    
    int KMP(char T[], char P[])//T主串,P模式串
    {
       int* Next = GetNext(P);
       if (Next == NULL) return -1;
       int i = 0;
       int j = 0;
       while (i < (int)strlen(T) && j < (int)strlen(P))
       {
       	if (j == -1 || T[i] == P[j])
       	{
       		i++;
       		j++;
       	}
       	else
       	{
       		j = Next[j];
       	}
       }
       printf("%d ", -1 < strlen(P));
       free(Next);
       return j == strlen(P) ? i - j : -1;
    }
    

    Details:

    strlen()函数的返回值是size_t类型,为无符号类型,而int是有符号类型。

    当无符号类型的与有符号类型相比较的时候,有符号类型会自动转换成无符号类型。

    程序显示,10 > -1 是FALSE(0)的。这就是类型转换的问题。由补码可知,-1的补码转换成无符号类型是一个很大的数字。

    所以说,代码中的循环条件比较时一定要进行强制类型转换!!!

    想深入了解KMP算法原理的小伙伴可以看看这个~
    KMP原理详解

  • 相关阅读:
    递归和回溯_leetcode-floodfill
    递归和回溯_leetcode131
    递归和回溯_leetcode130
    递归和回溯_leetcode93-经典的回溯题
    递归和回溯_leetcode90
    递归和回溯_leetcode79
    递归和回溯_leetcode78-经典的子集
    知识树杂谈(1)
    Android 设备兼容性(1)
    微信小程序- 生成二维码
  • 原文地址:https://www.cnblogs.com/ziyang1060/p/13247131.html
Copyright © 2011-2022 走看看