KMP count the string 暴力解法

来源:互联网 发布:用友网络股票分析 编辑:程序博客网 时间:2024/06/05 15:04
It is well known that AekdyCoin is good at string problems as well as number theory problems. When given a string s, we can write down all the non-empty prefixes of this string. For example:
s: "abab"
The prefixes are: "a", "ab", "aba", "abab"
For each prefix, we can count the times it matches in s. So we can see that prefix "a" matches twice, "ab" matches twice too, "aba" matches once, and "abab" matches once. Now you are asked to calculate the sum of the match times for all the prefixes. For "abab", it is 2 + 2 + 1 + 1 = 6.

The answer may be very large, so output the answer mod 10007.   

Input:

The first line is a single integer T, indicating the number of test cases.
For each case, the first line is an integer n (1 <= n <= 200000), which is the length of string s. A line follows giving the string s. The characters in the strings are all lower-case letters.

Output
For each case, output only one number: the sum of the match times for all the prefixes of s mod 10007.
Sample Input
14abab
Sample Output
6





分析:

这道题可以用KMP去做,但是我用的是暴力的方法,直接累加所有的字串。

具体算法是枚举出以每个字符开头的 子串, 就拿样例来说,abab  , 以第一个字符a开头的子串为 a,ab,aba,abab,有四个,以第二个字符b开头的字串为b,ba,bab,显然没有符合条件的,以第三个字符a开头的 a,ab,有两个,以第四个开头的,b,不符合条件;那么一共就是4+2 = 6.

再分析一个例子   abfeab

以第一个a开头的有六个(以第一个开头的个数一定是它的长度),以第二个,b,因为b != a,所以根本不会有,同样的f,e,都没有,到倒数第二个,a,  有a , ab,两个;

那么,在匹配了第一个字符后,我们就要再匹配后面的字符,匹配了多少次,答案就加多少


算法应该是很简单的了,首先一个for循环,从文本的第一个字符到最后一个字符,然后一个if ,判断当前的字符是不是和文本的第一个字符相同,如果相同,进一步的for循环,找能匹配多少个,答案就加多少,然后对10007取余,最后输出。


要注意的问题,子串和子串可以重叠,比如说  aaa, 子串是 a, aa,aaa,其中aa有两个,而不是一个,当然,用暴力的解法不用考虑这个。。。



下面是代码:
 

#include <iostream>#include <stdio.h>using namespace std;const int maxn = 2e5+4;char s[maxn];int main(){   int T,n;   scanf("%d",&T);   while(  T--  )   {   scanf("%d",&n);   int ans = n;//以第一个字符开头的前缀的个数是n,因为是从第二个开始,第一个就直接给出   ans = ans%10007;   scanf("%s",s);   for( int i = 1 ; i < n ; i++ )   {   if( s[i] == s[0] )//每个子串第一个字符一定要和文本字符的第一个 相同   {   for( int j = i ; j < n ; j++ )   {   if( s[j] == s[j-i] )// 每有一个相同的答案就 加1   ans++;   else break;   ans = ans%10007;   }   }   }   printf("%d\n",ans);   }    return 0;}



原创粉丝点击