编程随笔

来源:互联网 发布:java灵兽大乐斗 编辑:程序博客网 时间:2024/04/30 13:35

本节知识点:

1.KMP模式匹配算法,是为了避免普通字符串匹配算法中,没有必要的重复比较而设计的!在普通字符串比较中,通常有很多重复性的比较,KMP就是利用一个next数组当做索引,来避免这些重复性的比较!
2.对于具体算法的分析,本节不做过多叙述,详细可以参考<大话数据结构> 一书中的P135页。本节只做代码的保存!
示例代码:
[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. /************************************************************************************  
  2. 文件名:main.c 
  3. 头文件:无  
  4. 时间: 2013/03/31  
  5. 作者: Hao  
  6. 功能:KMP匹配算法的实现  
  7. 难点:1.KMP算法的分析 才是真正的难点  
  8. ************************************************************************************/   
  9. #include <stdio.h>  
  10. #include <stdlib.h>  
  11. #include <string.h>  
  12.   
  13.   
  14. /************************************************************************************  
  15. 函数名:   get_next 
  16. 函数功能: 获得子串的next数组  
  17. 参数:     const char* str 字串数组 即要匹配的字符串  int* next 获得的next数组  
  18. 返回值:   无  
  19. ************************************************************************************/  
  20. void get_next(const char* str ,int* next)  
  21. {  
  22.     int i, j;  
  23.     i = 1;  
  24.     j = 0;  
  25.     next[1] = 0; //这个规定node数组是从第1个位置开始的且为0  第0个位置不用    
  26.     while(i<strlen(str))  
  27.     {  
  28.         /*T[i]表示后缀的单个字符   T[j] 表示前缀的单个字符*/  
  29.         if((0 == j) || (str[i-1] == str[j-1]))    
  30.         {  
  31.             ++i;  
  32.             ++j;  
  33.             if(str[i-1] != str[j-1])   
  34.             {  
  35.                 next[i] = j;  
  36.             }   
  37.             else  
  38.             {  
  39.                 next[i] = next[j];  
  40.             }     
  41.         }  
  42.         else  
  43.         {  
  44.             j = next[j];  
  45.         }  
  46.     }   
  47. }   
  48.   
  49. /************************************************************************************  
  50. 函数名:   Index_KMP 
  51. 函数功能: 从主串Src到第pos位置开始 寻找子串str 出现的第一个位置  
  52. 参数:     const char* Src主串, const char* str子串, int pos重主串第pos位置开始寻找子串  
  53. 返回值:   成功 返回子串在主串中的第一个位置 
  54.            失败  即不存在匹配项 则返回-1 
  55. 注意:     pos是从0位置开始计算的   return的值是从1开始计算的   
  56. ************************************************************************************/  
  57. int Index_KMP(const char* Src, const char* str, int pos)  
  58. {  
  59.     int i = pos; //i永远是主串的下标   i永远不回溯   
  60.     int j = 0;       //j是子串的下标    j要根据next数组进行回溯   
  61.     int next[100];  
  62.     get_next(str ,next);  
  63.     /*当i = strlen(Src) 说明主串遍历结束*/  
  64.     /*当j = strlen(str) 说明子串匹配完成*/   
  65.     while( (i < strlen(Src) ) && (j < strlen(str)) )    
  66.     {  
  67.         if((0 == j) || (Src[i-1] == str[j-1]))  
  68.         {  
  69.             ++i;  
  70.             ++j;   
  71.         }  
  72.         else  
  73.         {  
  74.             j = next[j]; // 匹配失败 j进行回溯   
  75.         }   
  76.           
  77.     }  
  78.     if(j == strlen(str)) // 是子串匹配成功的情况  跳出的while循环   
  79.     {  
  80.         return i - j + 1;   
  81.     }   
  82.     else  
  83.     {  
  84.         return -1;  
  85.     }  
  86.        
  87. }   
  88.   
  89. int main(int argc, char *argv[])   
  90. {  
  91.     char* p = "ababaaaba";  
  92.     char* s = "aab";  
  93.   
  94.     printf("%d\n",Index_KMP(p, s, 0));  
  95.     printf("%d\n",Index_KMP(p, s, 5));  
  96.     printf("%d\n",Index_KMP(p, s, 6));  
  97.     return 0;  
  98. }  
0 0