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
s
three times. In other words, find any most frequent two-gram.
Note that occurrences of the two-gram can overlap with each other.
Input
The 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
n
capital Latin letters.
Output
Print 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.
Examples Input
7 ABACABA
Output
AB
Input
5 ZZZAA
Output
ZZ
Note
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;
}