KMP算法的代码实现与讲解

const char *str  = "bacbababadababacambabacaddababacasdsd";

const char *ptr = "ababaca";

我们按照上篇博文的理解来思考,要计算next数组,

 按照下图中的下标分别存储在 0 1 2 3 4 5 6 中

KMP算法的代码实现与讲解_第1张图片


我们提出需求: 1.  首先, 对于每个子串找最长公共前后缀的长度,应该把每个子串列举出来 

                        

                            怎么表示呢?  用一个for就行了

                               for(int i = 0; i < len; ++i)

                               {

                               }

                                                                                                        

                         2.         

                                    a                没有最长公共前后缀,  不用算,我们手动赋值为 next[0] = -1

                                     j  

                                    ab              比上一个串多了字符 b,a与b不同,所以          next[1] =  上一次的结果(原因后面)  

                                     j    

                                    aba           比上个串多了个a,而且上一个串的next[1]告诉我们,上个串没有公共前后缀。

                                                     由于新增的a == 开头a,所以存在最长公共前后缀  next[2] = next[1]+1;//实际为1,记0

                                      j                 

                                    abab         比上一串多了个b,由于上一串有最长公共前后缀且长度为 nxet[2], 且多出的b与 j所指向的b相同,所以,next[3] = next[2] +1;(用上一步的结果)

                                         j                                       

                                    ababc        新增c,与j指向的a不同,所以最长公共子缀直接不复存在,记为 -1

                                    。。。。。。。。。



代码实现:

#include 
#include 
#define debug(); cout<<__LINE__< -1 && ptr[i] != ptr[j+1]) //不等next等j
                        j = next[j];

                if( ptr[i] == ptr[j+1] ) // 等子串j加加
                        j++;
                next[i] = j;
        }

        for(int i = 0; i < len; ++i)
                cout << next[i] << ' ';
                cout << endl;
}

int KMP( )
{
        Get_next();
        int s_len = strlen(str);
        int p_len = strlen(ptr);
        int j  = -1;
        for(int i = 0; i < s_len; ++i)
        {
                while(j > -1 && ptr[j+1] != str[i])
                        j = next[j];
        
                if(ptr[j+1] == str[i])
                        j++;
        
                if(j == p_len-1) 
                        return i-p_len+1;
        }
        return -1;
}                       
                
int main( )
{
        cout << KMP( ) << endl;
}      

你可能感兴趣的:(algorithm)