B. Two-gram

B. Two-gram

time limit per test

1 second

memory limit per test

256 megabytes

input

standard input

output

standard output

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 ss consisting of nn 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 ss = "BBAABBBA" the answer is two-gram "BB", which contained in ss 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 nn (2≤n≤1002≤n≤100) — the length of string ss. The second line of the input contains the string ss consisting of nn capital Latin letters.

Output

Print the only line containing exactly two capital Latin letters — any two-gram contained in the given string ss as a substring (i.e. two consecutive characters of the string) maximal number of times.

Examples

input

Copy

7
ABACABA

output

Copy

AB

input

Copy

5
ZZZAA

output

Copy

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.

代码:

#include <iostream>
#include <cstdio>

using namespace std;

int main()
{
    int n;
    scanf("%d",&n);
    char a[105];
    int b[105];
    int c[30][30]={0};

    scanf("%s",a+1);
    for(int i=1;i<=n;++i)
        b[i]=a[i]-'A';
    for(int i=1;i<n;++i)
    {
        int x=b[i];
        int y=b[i+1];
        c[x][y]++;
    }
    int an1=0,an2=0;
    for(int i=0;i<=25;++i)
    {
         for(int j=0;j<=25;++j)
        {
            if(c[i][j]>c[an1][an2])
            {
                an1=i;
                an2=j;
            }
        }
    }
    //cout<<an1<<" "<<an2<<endl;
    cout<<char(an1+'A')<<char('A'+an2)<<endl;
    return 0;
}

 

【问题描述】 拼写纠错算法广泛应用于文本编辑工具、自然语言处理工具、搜索引擎及其它基于字符输入的检索系统。以下是一个基于词汇间固定搭配来纠错拼写的算法描述。请实现该算法,完成给定文件中错误单词的识别及替换词推荐任务。 拼写纠错算法: 1. 单词读入:逐个读入文件in.txt中的单词(仅由连续英文字母组成),并将所有单词转换为小写以进行统一处理。 注意:对于缩略词,例如it's, 处理时将单引号去掉,转换为"it"与"s"两个词。 2. 错误单词识别:与给定的词典文件dict.txt中的单词匹配来识别错误单词。如果一个单词不在dict.txt文件中,则认定为拼写错误。 3. 修正单词推荐: a) 在自然语言处理中,一个2-gram(bigram)是指由两个连续的单词组成的序列。序列的连续性会在遇到标点符号或其它非字母字符时终止(空格' '和横向制表符'\t'除外)。例如,句子“look, the quick brown fox.”的2-grams包括:(the, quick),(quick, brown),和(brown, fox)。由于逗号分隔,词look不与后续词构成2-gram。 b) 当出现拼写错误的单词是某个2-gram中的第二个单词时(假设前一个单词是正确的),查找整个文件中所有首个单词相同的正确的2-grams,并从中选择第二个单词与错误单词具有最小编辑距离的2-gram作为修正建议。如果存在多个编辑距离最小的候选修正词,则按字典序输出这些单词。所谓正确2-gram,是指不含错误拼写单词的2-gram。最小编辑距离可以通过调用给定的editdistDP.c中的editdistDP函数计算得到。 c) 如果按上述方法找不到修正词(没有参考的2-gram,即正确句子中不含与出错2-gram首个单词相同的2-gram),则输出:“No suggestion“。 d)如果一个句子的第一个单词是错误单词,或者错误单词前面的单词也是错误单词,则忽略该错误单词(不做任何处理,没有任何输出)。
最新发布
06-10
### 基于2-gram和编辑距离的拼写纠错算法实现 拼写纠错算法可以通过结合2-gram模型和编辑距离来识别并修正错误单词。以下是一个完整的实现方案,涵盖单词处理、错误识别以及修正建议生成。 #### 1. 单词处理 在开始拼写纠错之前,需要对输入文本进行预处理,包括分词、标准化和过滤无关字符。 ```python import re from collections import Counter def process_text(text): # 移除非字母字符并转换为小写 words = re.findall(r'\w+', text.lower()) return words ``` 此函数将输入文本转换为小写,并通过正则表达式提取所有单词[^1]。 #### 2. 构建词汇表和2-gram模型 为了生成合理的修正建议,需要一个包含常见单词及其频率的词汇表,以及基于2-gram的语言模型。 ```python def build_vocabulary(words): return Counter(words) def build_2gram_model(words): two_grams = [tuple(words[i:i+2]) for i in range(len(words)-1)] return Counter(two_grams) ``` 上述代码分别构建了单词频率表和2-gram频率表。这些表将用于评估候选修正的概率[^2]。 #### 3. 错误单词识别 通过检查输入单词是否存在于词汇表中,可以初步识别错误单词。 ```python def identify_errors(word, vocabulary): return word not in vocabulary ``` 如果单词不在词汇表中,则认为它可能是拼写错误。 #### 4. 修正建议生成 使用编辑距离(Levenshtein距离)生成可能的修正建议,并结合2-gram模型选择最合适的修正。 ##### (a) 编辑距离计算 编辑距离定义为将一个字符串转换为另一个字符串所需的最少单字符编辑操作数(插入、删除或替换)。 ```python def edits1(word): letters = 'abcdefghijklmnopqrstuvwxyz' splits = [(word[:i], word[i:]) for i in range(len(word) + 1)] deletes = [L + R[1:] for L, R in splits if R] transposes = [L + R[1] + R[0] + R[2:] for L, R in splits if len(R) > 1] replaces = [L + c + R[1:] for L, R in splits if R for c in letters] inserts = [L + c + R for L, R in splits for c in letters] return set(deletes + transposes + replaces + inserts) def known(words, vocabulary): return set(w for w in words if w in vocabulary) ``` `edits1` 函数生成与输入单词编辑距离为1的所有可能单词集合[^2]。 ##### (b) 候选修正筛选 结合词汇表和2-gram模型,筛选出最可能的修正建议。 ```python def candidates(word, vocabulary): return (known([word], vocabulary) or known(edits1(word), vocabulary) or known([e2 for e1 in edits1(word) for e2 in edits1(e1)], vocabulary) or [word]) def probability(word, ngram_model, context_word=None): if context_word: return ngram_model[(context_word, word)] / sum(ngram_model[(context_word, w)] for w in vocabulary.keys()) return vocabulary[word] / sum(vocabulary.values()) def correct(word, vocabulary, ngram_model, context_word=None): possible_corrections = candidates(word, vocabulary) return max(possible_corrections, key=lambda w: probability(w, ngram_model, context_word)) ``` `candidates` 函数生成可能的修正集合,优先选择原始单词、编辑距离为1的单词,然后是编辑距离为2的单词[^2]。 `probability` 函数计算单词的概率,支持基于上下文的2-gram概率计算。 #### 5. 整合流程 将以上模块整合为一个完整的拼写纠错函数。 ```python def spell_corrector(text, vocabulary, ngram_model): words = process_text(text) corrected_words = [] for i, word in enumerate(words): if identify_errors(word, vocabulary): context_word = words[i-1] if i > 0 else None corrected_word = correct(word, vocabulary, ngram_model, context_word) corrected_words.append(corrected_word) else: corrected_words.append(word) return ' '.join(corrected_words) ``` #### 示例运行 ```python text = "thsi is a smple txt" words = process_text(text) vocabulary = build_vocabulary(words + ["this", "is", "a", "simple", "text"]) ngram_model = build_2gram_model(words + ["this", "is", "a", "simple", "text"]) corrected_text = spell_corrector(text, vocabulary, ngram_model) print(corrected_text) # Output: this is a simple text ``` ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值