• HDU 1711(KMP)字符串匹配



         

    链接  HDU 1711 Number Sequence

    KMP 算法

          我以自己理解写的,写的不对,不明白的地方海王子出来,一起共同学习;

    字符串匹配 就是KMP,一般思想,用一个for循环找开头   如果开头一样进入第二个for循环;这样统计  直观 容易理解。但是时间复杂度比较长。所以就有KMP  这个算法了

       KMP 大体思想因为在上一个方法之中,有的字符重复比较了,使得找到目标字符窜效率比较低,


    比如   :目标串为:   ① a b a b c 

                  在                 ② a b a a b a b c d a b c d b c  这个字符窜中找到上述目标串;

    如用  i,j  来表示①,②两个字符串的下标,假设下标从一开始;

    i=1,j=1    a=a;

    i=2,j=2    b=b;

    i=3,j=3    a=a;

    i=4;j=4    b!=a;  此时如果只将①字符串右移动一位,虽然可以;但是,假如你移动两位看看怎么样?

               a b a b c 

         a b a a b a b c d a b c d b c 

    是不是觉得移动2格对得非常整齐?

    那么为什么移动两个?

    第3个a与第一个a正好重复!所以我们知道重复单元就知道移动多少。需要一个数组记录当两个字符不相等,i 应该指向哪个!记录重复单元的值,叫做部分匹配值!不懂可以百度部分匹配值!以上就是KMP 核心思想

    下面贴一个代码!!两种写法!//屏蔽是另一种写法

    [cpp] view plain copy
    1. #include<iostream>  
    2. #include<stdio.h>  
    3. #include<string.h>  
    4. #include<algorithm>  
    5.   
    6. using namespace std;  
    7.   
    8. int N[1000005],M[10005],a[10005],n,m;  
    9. void set_a()  
    10. {  
    11.     int i,j;  
    12.     a[1]=0;  
    13.     j=1;  
    14.     for(i=2; i<=m; i++)  
    15.     {  
    16.         if(M[j]==M[i])  
    17.         {  
    18.             a[i]=j;  
    19.             j++;  
    20.         }  
    21.         else if(M[j]!=M[i]&&M[i]==M[1])  
    22.         {  
    23.             a[i]=1;  
    24.             j=2;  
    25.         }  
    26.         else  
    27.         {  
    28.             a[i]=0;  
    29.             j=1;  
    30.         }  
    31.     }  
    32. //    for(i=1; i<=m; i++)  
    33. //        printf("%d ",a[i]);  
    34. //    printf(" ");  
    35. }  
    36. int kmp()  
    37. {  
    38.     int i=1,j=1,k;  
    39.     set_a();  
    40.     while(i<=n)  
    41.     {  
    42.         if(j==1&&N[i]!=M[j]) i++;  
    43.         if(N[i]==M[j])  
    44.         {  
    45.             i++;  
    46.             j++;  
    47.         }  
    48.         else j=a[j-1]+1;  
    49.         if(j==m+1) return i-m;  
    50.     }  
    51.     return -1;  
    52. }  
    53. int main()  
    54. {  
    55.     int t;  
    56.     scanf("%d",&t);  
    57.     while(t--)  
    58.     {  
    59.         //int b; scanf("%d",&b);  
    60.         int i;  
    61.         scanf("%d%d",&n,&m);  
    62.         memset(a,0,sizeof(a));  
    63.         for(i=1; i<=n; i++)  
    64.             scanf("%d",&N[i]);  
    65.         for(i=1; i<=m; i++)  
    66.             scanf("%d",&M[i]);  
    67.         printf("%d ",kmp());  
    68.     }  
    69.     return 0;  
    70. }  
    71.   
    72. ///**********************KMP****************************/  
    73. //  
    74. //#include<stdio.h>  
    75. //#include<string.h>  
    76. //using namespace std;  
    77. //int lena,lenb;  
    78. //int a[1000005],b[10005];  
    79. //int next[200000];  
    80. //void set_naxt()//子串的next数组  
    81. //{  
    82. //    int i=0,j=-1;  
    83. //    next[0]=-1;  
    84. //    while(i<lenb)  
    85. //    {  
    86. //        if(j==-1||b[i]==b[j])  
    87. //        {  
    88. //            i++;  
    89. //            j++;  
    90. //            next[i]=j;  
    91. //        }  
    92. //        else  
    93. //            j=next[j];  
    94. //    }  
    95. //    // printf(">>%d ",next[lenb-1]);  
    96. //    for(i=1; i<=lenb; i++)  
    97. //        printf("%d ",next[i]);  
    98. //    printf(" ");  
    99. //}  
    100. //  
    101. //int kmp()  
    102. //{  
    103. //    int i=0,j=0;  
    104. //    set_naxt();  
    105. //    while(i<lena)  
    106. //    {  
    107. //        if(j==-1||a[i]==b[j])  
    108. //        {  
    109. //            i++;  
    110. //            j++;  
    111. //        }  
    112. //        else  
    113. //            j=next[j];  
    114. //        if(j==lenb)  
    115. //            return i-j+1;  
    116. //    }  
    117. //    return -1;  
    118. //}  
    119. //int main()  
    120. //{  
    121. //    int i,t;  
    122. //    scanf("%d",&t);  
    123. //    while(t--)  
    124. //    {  
    125. //        memset(next,0,sizeof(next));  
    126. //        scanf("%d%d",&lena,&lenb);  
    127. //        for(i=0; i<lena; i++)  
    128. //            scanf("%d",&a[i]);  
    129. //        for(i=0; i<lenb; i++)  
    130. //            scanf("%d",&b[i]);  
    131. //        printf("%d ",kmp());  
    132. //    }  
    133. //}  



  • 相关阅读:
    CSS3 定位| Position研究
    ASP.NET中Partial Class部分类
    如何安全实现“记住我”的功能
    JavaScript后台代码操作HTML TABLE的方法
    强悍的CSS工具组合:Blueprint, Sass, Compass
    CSS的力量:用一个DIV画图
    ASP.NET记录错误日志的方式
    ASP.NET私有构造函数作用
    c#.net实现浏览器端大文件分块上传
    asp.net实现浏览器端大文件分块上传
  • 原文地址:https://www.cnblogs.com/coded-ream/p/7208017.html
Copyright © 2020-2023  润新知