hdu 3336 KMP

Count the string

 1 /*
 2 写于13年3月21日
 3 http://acm.hdu.edu.cn/showproblem.php?pid=3336
 4 2013-03-21 10:39:01    Accepted    3336    46MS    2016K
 5 很巧妙的利用了KMP函数get_next()的思想
 6 通过对其进行改写达到目的
 7 data[i]表示[1....i]字符串出现的次数
 8 */
 9 
10 #include <iostream>
11 #include <stdio.h>
12 #include <string.h>
13 using namespace std;
14 
15 char s[200005];
16 int next[200005];
17 int data[200005];
18 
19 void get_next(int n)
20 {
21     int j=0,i=1;
22     next[1]=0;
23     memset(data,0,sizeof(data));//将data初始化
24     while(i<=n)
25     {
26         if(j==0||s[i]==s[j])
27         {
28             ++data[i];//字符串[1...i]第一次出现时置为1
29 
30             ++i;
31             ++j;
32             next[i]=j;
33             /*get_next的优化算法,但此处用不上
34             if(s[i]!=s[j])
35                 next[i]=j;
36             else
37                 next[i]=next[j];
38 
39             */
40             //j>1表示此时有s[i-1]==s[j-1],即有[1...j-1]出现第二次或更多次,j<n
41             if(j>1)
42                 data[j-1]++;
43         }
44         else
45             j=next[j];
46     }
47 }
48 int main()
49 {
50     int t;
51     int n;
52     scanf("%d",&t);
53     while(t--)
54     {
55         int ans=0;
56         scanf("%d",&n);
57         /*
58         for(int i=1;i<=n;i++)
59             scanf("%c",&s[i]);
60         此时%c接受空格回车等,就是在这里调试了一晚上,囧!
61         以后要改用c++了!
62         */
63         scanf("%s",s+1);//字符串从s[1]开始
64         get_next(n);
65         for(int i=1;i<=n;i++)
66         {
67             //各个前缀出现的总次数和
68             ans=(ans+data[i])%10007;
69         }
70         ans=(ans)%10007;
71         printf("%d\n",ans);
72     }
73     return 0;
74 }

 

posted on 2013-03-21 10:40  行者1992  阅读(170)  评论(0编辑  收藏  举报