zoukankan      html  css  js  c++  java
  • Lec2KMP实现

    贴代码:

     1 #include <iostream>
     2 #include <cstring>
     3 #include <cstdio>
     4 using namespace std;
     5 //kmp:快速字符串匹配
     6 
     7 //关于返回值:需要返回一个大小为pattern_size的存放next值的数组,如果只在函数中定义临时变量的数组,则无法返回值;
     8 //而如果在函数中new一个数组返回,则需要在外面delete,违反了程序设计的准则。
     9 //较好的方法是在main中构造一个数组然后把首指针传到函数中去
    10 
    11 //关于函数设计:先给出递推式,明确设计方法
    12 //next函数设计方法:(1)next[1]=0;当比较不相等时且遇到next[1]=0,说明遇到串头,主串需要往后移一位
    13 //递推:当next[j]=k时,有P1....Pk-1 = Pj-k+1....Pj-1   (2)若Pj = Pk,则next[j+1] = k + 1 = next[j] + 1
    14 //(3)若Pj != Pk,因为有P1....Pk-1 = Pj-k+1....Pj-1,对于next[k] = k'也会满足k'之前的字符等于j之前的字符,这种性质能通过next函数传递
    15 //于是递推移动k' = next[k],若有Pj = Pk',则next[j] = k' +1。如果遇到next[1]=0,则next[j] = 1。
    16 void compute_next(char * pattern,int len, int *next)
    17 {
    18     next[1= 0;//next函数对应的是模式串的位数
    19     int j = 1;
    20     while(j < len) 
    21     {
    22         int k = next[j];
    23         //if(k == 0)     { next[j+1] = 1;cout<<j+1<<next[j+1]<<endl;  j++; continue;}
    24         //if (pattern[j-1] == pattern[k-1]) 
    25         //{
    26         //    next[j+1] = next[j] +1;
    27         //    cout<<j+1<<next[j+1]<<endl;
    28         //}
    29         //else
    30         //{           //有一个简化的过程
    31             while(k != 0)
    32             {
    33                 if (pattern[j-1== pattern[k-1])  
    34                 {
    35                     next[j+1= k + 1;
    36                     cout<<j+1<<next[j+1]<<endl;   //经验:将中间结果输出可以节省调试时间,快速发现问题(避免单步!)
    37                     break;
    38                 }
    39                 k = next[k]; //这种迭代的方法很巧妙,看书~
    40             }
    41             if(k == 0
    42             {
    43                 next[j+1= 1;
    44                 cout<<j+1<<next[j+1]<<endl;
    45             }
    46         //}
    47         j++;
    48     }
    49 }
    50 
    51 int kmp(char* source,int lens,char* pattern,int lenp,int *next)
    52 {
    53     int i =1, j=1;
    54     while(i<=lens&&j<=lenp)
    55     {
    56         if (j == 0 || source[i-1== pattern[j-1])
    57         {
    58             i++;
    59             j++;
    60         }
    61         else j = next[j];
    62     }
    63     if(j>lenp) return (i - lenp);
    64     else return 0;
    65 }
    66 
    67 int main()
    68 {
    69     char source[100];
    70     char pattern[100];
    71     int s_size,p_size;
    72 
    73     while(1)
    74     {
    75 
    76         cout<<"Input the first string:";
    77         cin>>source;
    78         cout<<"Input the second string:";
    79         cin>>pattern;
    80         s_size = strlen(source);
    81         p_size = strlen(pattern);
    82 
    83         int next[100];
    84         compute_next(pattern, p_size,  next); 
    85         //kmp算法的关键是求出模式串的next函数,即当前模式串的第j位与目标串的第i位不相等时,
    86         //下一步应使用模式串的next(j)位与目标串第i位进行比较
    87         //next(j)=k,即有P1....Pk-1 = Pj-k+1....Pj-1
    88         int result = kmp(source,s_size,pattern,p_size,next);
    89         cout<<"The substring index is "<<result<<endl;
    90     }
    91 }
  • 相关阅读:
    IPC框架分析 Binder,Service,Service manager
    Android语音系列:编译Speex框架
    Android核心分析(21)Android应用框架之Android Application
    支付宝 移动支付
    对象、视频、音频的传输RTMP协议研究
    ffmpeg 移植篇笔记
    iPhone UI 设计篇(一)
    Service深入分析
    CSS注意事项
    关于文本断行的样式
  • 原文地址:https://www.cnblogs.com/avril/p/2032065.html
Copyright © 2011-2022 走看看