Two-gram
Two-gram is an ordered pair (i.e. string of length two) of capital Latin letters. For example, "AZ", "AA", "ZA" — three distinct two-grams.
You are given a string s
consisting of n capital Latin letters. Your task is to find any two-gram contained in the given string as a substring (i.e. two consecutive characters of the string) maximal number of times. For example, for string s = " BBAABBBA" the answer is two-gram " BB", which contained in sthree times. In other words, find any most frequent two-gram.
Note that occurrences of the two-gram can overlap with each other.
InputThe first line of the input contains integer number n
( 2≤n≤100) — the length of string s. The second line of the input contains the string s consisting of ncapital Latin letters.
OutputPrint the only line containing exactly two capital Latin letters — any two-gram contained in the given string s
as a substring (i.e. two consecutive characters of the string) maximal number of times.
Examples7 ABACABA
AB
5 ZZZAA
ZZ
In the first example "BA" is also valid answer.
In the second example the only two-gram "ZZ" can be printed because it contained in the string "ZZZAA" two times.
子串长度是2,所以直接暴力选子串,然后kmp匹配不断更新出现次数最多的子串为答案
我的思路很简单,暴力枚举子串,kmp找出现次数,写起来相对复杂,当然也可以暴力找出现次数时间复杂度都是可以的
code:
#include <bits/stdc++.h> using namespace std; int n; char s[120]; char w[4]; char ans[4]; int Next[120]; int maxt; void getNext(){ int i = -1,j = 0; Next[0] = -1; while(j < 2){ if(i == -1 || w[i] == w[j]){ i++,j++; if(w[i] == w[j]) Next[j] = Next[i]; else Next[j] = i; } else i = Next[i]; } } void kmp(){ getNext(); int i = 0,j = 0; int cnt = 0; while(j < n){ if(i == -1 || s[j] == w[i]){ i++,j++; } else i = Next[i]; if(i == 2) cnt++; } if(cnt > maxt){ maxt = cnt; strcpy(ans,w); } } int main(){ scanf("%d",&n); scanf("%s",s); maxt = 0; for(int i = 0; i < n-1; i++){ w[0] = s[i]; w[1] = s[i+1]; w[2] = 0; kmp(); } printf("%s\n",ans); return 0; }
下面是我队友的巧妙思路
code:
#include <iostream> #include <cstdio> #include <cstring> using namespace std; int dp[30][30]; int main(){ int n; string str; cin >> n >> str; for(int i = 0; i < n-1; i++){ int x = str[i] - 'A'; int y = str[i+1] - 'A'; dp[x][y]++; } int maxt = 0,Last = 0,Next = 0; for(int i = 0; i < 26; i++){ for(int j = 0; j < 26; j++){ if(maxt < dp[i][j]){ Last = i; Next = j; maxt = dp[i][j]; } } } printf("%c%c\n",Last + 'A',Next + 'A'); return 0; }