这个KNP字符串匹配算法有什么问题?

时间:2013-05-26 08:50:44

标签: c string-matching

我根据维基百科中的KNP

编写了基于伪代码的KNP

但不幸的是,它似乎没有给出正确的结果。

#include <stdio.h>
#include <stdlib.h>

void getNext(char *p, int next[])
{
  int i, j;
  int m = strlen(p);
  next[0] = -1;

  for(j=1; j<m; j++)
  {
    i = next[j - 1]; 
    while((i >= 0) && (p[j - 1] != p[i]))
    {
        i = next[i];
    }
    next[j] = i+1;
  }
}

int knp(char *text, char* pattern, int T[])
{
  int m = 0; // The beginning of the current match in text
  int i = 0; // The position of the current character in W

  int pattern_length = strlen(pattern) - 1;

  while( m+i < pattern_length)
  {
     if( pattern[i] == text[m+i]) // Made a mistake here and wrote: text[m]
      {
         if(i == )
         {
                 return m;
             }
             else
                 i = i + 1;
       }
       else
       {
           if( T[i] > -1 )
              i = T[i];
           else
              i = 0;

             m = m + i - T[i];
       }
  }
  return -1; // If we reach here, the string is not found
}
int main()
{
  int next[7];
  int i;
  char *ptr = "ababaca";
  char *text = "ababbababaaaababacaacd";

  getNext(ptr, next);
  for(i=0; i<7; i++)
  {
    printf("%d\t",next[i]);
  }
  printf("\n");

  printf("Pattern match at: %d",knp(text, ptr, next));
}

注意:只有KNP来自wiki。我从另一本书中获取的表格构建理念;-),验证它确实给出了与wiki中匹配的正确结果。

以上代码现已更正(根据迈克尔的回答),以便每个人都受益。我已经把我的错误(以注释掉的形式)放在这里,因为这里提出了问题。

1 个答案:

答案 0 :(得分:1)

你的转录中写了一个错字:

if( pattern[i] == text[i])

应该是:

if( pattern[i] == text[m + i])

我还建议您从循环中删除对strlen(pattern)的调用,并在循环开始之前调用它。