返回列表 发帖

[分享] 数据结构--串的应用,模式匹配算法(从简单算法到改进的KMP算法)

这一篇写的模式匹配算法是以上一篇串的基本操作为基础的,这里面写了模式匹配的三种不同的算法,其实每个算法都是前一算法的改进,有简单匹配,头尾匹配,还有改进后KMP算法

这是文件fun.h:
  1. #ifndef FUN_H
  2. #define FUN_H
  3. #include "mystring.h"

  4. int Index(String *sub,String *s,int pos); //匹配的简单算法:返回子串sub在主串s中的位置,失败则返回0
  5. int Index_HeadToTail(String *sub,String *s,int pos);//匹配的改进算法:头尾同时进行比较
  6. void get_next(String *,int []);    //KMP算法中的next函数算法
  7. int kmp(String *s,String *T,int [],int pos); //KMP的改进算法

  8. int Index(String *sub,String *s,int pos)
  9. {
  10. int i,j;
  11. if(pos<0||pos>s->length)  exit(OVERFLOW);
  12. i=pos-1;
  13. j=0;
  14. while(i<s->length && j<sub->length)
  15. {
  16.   if(s->ch[i]==sub->ch[j])
  17.   {
  18.    ++i;++j;
  19.   }
  20.   else
  21.   {
  22.    i=i-j+2;
  23.    j=0;
  24.   }
  25.     }
  26. if(j==sub->length)  
  27. {
  28.   printf("Success!");
  29.   TURNLINE;
  30.   return i-sub->length;//匹配成功,并且此时i,j的位置都在'\0'上,则返回在主串中匹配的第一个位置
  31. }
  32. else
  33. {
  34.   printf("Failed!");
  35.   TURNLINE;
  36.   return 0;
  37. }
  38. }
  39. int Index_HeadToTail(String *sub,String *s,int pos)
  40. {
  41. int i,j=1,k=1;
  42. i=pos-1;
  43. while(i<s->length)
  44. {
  45.   if(s->ch[i]!=sub->ch[0]) ++i;  //如果头字符匹配不成功则继续匹配下一个
  46.   else if (s->ch[i+sub->length-1]!=sub->ch[sub->length-1])  ++i; //如果头字符匹配成功,但尾字符匹配不成功,继续匹配下一个
  47.   else
  48.   {  
  49.      while(j<sub->length && s->ch[i+k]==sub->ch[j])
  50.      {
  51.       ++k;++j;
  52.      }
  53.      if(j==sub->length)  
  54.      {
  55.       printf("Success!");
  56.       TURNLINE;
  57.       return i;
  58.      }
  59.      else
  60.      {
  61.       printf("Failed");
  62.       TURNLINE;
  63.       return 0;
  64.      }
  65.   }
  66. }
  67. return 0;
  68. }

  69. void get_next(String *s,int next[])
  70. {
  71. int i,j;
  72.     next[0]=-1;
  73. i=0;
  74. j=-1;
  75. while(i<s->length)
  76. {
  77.   if(j==-1||s->ch[i]==s->ch[j])
  78.   {
  79.    ++i;
  80.    ++j;
  81.    if(s->ch[i]!=s->ch[j])  next[i]=j;
  82.    else next[i]=next[j];
  83.   }
  84.   else j=next[j];
  85. }
  86. }
  87. int kmp(String *s,String *T,int next[],int pos)
  88. {
  89. int i,j;
  90.    
  91. if(pos<1||pos>s->length)
  92.           exit(OVERFLOW);
  93. i=pos-1;
  94. j=0;
  95. while(i<s->length && j<T->length)
  96. {
  97.   if(s->ch[i]==T->ch[j] || j==-1)
  98.   {
  99.    ++i;
  100.    ++j;
  101.   }
  102.   else j=next[j];
  103. }
  104. if(j==T->length)
  105. {
  106.   printf("Success!");
  107.   TURNLINE;
  108.   return   i-T->length;
  109. }
  110. else
  111. {
  112.   printf("Failed!");
  113.   TURNLINE;
  114.   return 0;
  115. }
  116. }

  117. #endif
复制代码
这是mian函数:
  1. #include "mystring.h"
  2. #include "fun.h"
  3. int main()
  4. {
  5. String str1,str2,str3;
  6. int index,next[10];
  7. int i;
  8. char *chars="aaaababaabcacaabc\0";
  9. char *chars1="ababa\0";

  10. strAssign(&str1,chars);
  11. /*strCopy(&str1,&str2);*/

  12. strAssign(&str2,chars1);
  13. get_next(&str2,next);
  14. strPrint(&str1);
  15. strPrint(&str2);
  16. for(i=0;i<5;++i)
  17. printf("%3d",next[i]);TURNLINE;

  18. index=kmp(&str1,&str2,next,1);
  19. printf("%d\n",index);
  20. return 0;
  21. }
复制代码

返回列表