字符串匹配之三:拼写错误检查程序

DNA的匹配毕竟离生活还是远了点,既然是字符串匹配,可不可以做个拼写错误检查呢?

首先要引入一个概念,编辑距离(Edit Distance)。编辑距离指的是一个字符串修改到另一个字符串所需要的工序。通常有三种情况:

1.插入:"ac" -----> "abc",编辑距离为1

2.删除:"abc" ------> "ac", 编辑距离为1

3.替换:"abc" ------>"adc", 编辑距离为1

在这里我们定义两个字符串 x 和 y 的编辑距离为:

dist = len(x) + len(y) - score(x, y)

score指的是全局匹配返回的分数。但是scoring_matrix怎么办呢?我找了一些我自己可以数得出来编辑距离的字符串,然后把一些可能的值一个一个去算。这里提到的scoring_matrix的参数有三个:diag_score(字符相同), off_diag_score(两个字符,但是不同), dash_score(一个字符,一个 ‘-‘ )。然后发现了这三个值分别是:

diag_score: 2
off_diag_score: 1
dash_score: 0

这里注意的是,别选择过于复杂的字符串,那样的话编辑距离很容易数错,比如"abcdged"与"acdad",我们仅仅靠自己匹配,很难找出最佳的匹配。

在源代码中也有一个word_list.txt,里面存放了7万多个单词。这样我们就可以从中与给定字符串相差固定编辑距离的单词了。

def check_spelling(checked_word, dist, word_list):

    alphabet = set('qwertyuiopasdfghjklzxcvbnm')
    scoring_matrix = scoring_matrix = build_scoring_matrix(alphabet=alphabet, diag_score=2, off_diag_score=1, dash_score=0)

    answer = set([])
    for word in word_list:
        edit_distance = get_edit_distance(checked_word, word, scoring_matrix)
        if edit_distance <= dist:
            answer.add(word)
    return answer

其中get_edit_distance其实就是按照前面给出的公式计算出编辑距离的函数。我稍微测试了一下,寻找编辑距离为1的相似单词,十几秒就可以完成(可能是我的电脑的配置较高的缘故)。但是拼写检查还是追求的实时性,我一旦写错了一个单词,按下空格的时候,就应该有提示。十几秒不是可以接受的。

————————番外————————

这里测试了一下set和list的迭代效率,发现list的迭代效率高于set,而查找一个元素是否在对象内,set的效率远超list,而且set占据的内存相对list要下

————————番外结束——————

当用户输入一个单词,我们首先可以查找单词是否在正确拼写的单词集合内(查找一个对象是否在一个集合的效率是很高的)。如果不在,就打上波浪线,然后就可以进入查找dist为1或者2的单词集合了。

我突然想到word早期版本的拼写错误检查,打波浪线很快,但是进行拼写错误检查的时候要等半天,是否就是采用这样的办法?

然后进入查找程序之后,进行匹配之前,可以先检查单词的长度,如果长度相差多于给定的dist,那么就不用进入匹配了,直接抛弃即可。效率应该又可以提高一些。

在互联网的时代,云计算的性能不言而喻,而在线编辑的时候也要实时保存,传送一个单词的带宽也很窄,因此可以把计算放到云上,这样几乎就是实时的。而检查一个单词是否在正确拼写的集合内的操作可以让JavaScript来做,既可以减轻服务器的负担,在用户这边,又感觉不到丝毫的卡滞。

一口气写完了字符串匹配的三篇文章,真是神清气爽,而文章的抄袭检查也是呼之欲出了。因为最近要找工作,第四篇可能会稍微晚一点,敬请期待吧。

源代码:Github

时间: 2024-10-13 02:35:18

字符串匹配之三:拼写错误检查程序的相关文章

uva:10340 - All in All(字符串匹配)

题目:10340 - All in All 题目大意:给出字符串s和t,问s是否是t的子串.s若去掉某些字符能和t一样,那么t是s的子串. 解题思路:匹配字符.t的每个字符和s中的字符匹配.注意这里的字符数组大小要开大点. 代码: #include <stdio.h> #include <string.h> const int N = 1000005; char s[N], t[N]; bool match () { int i = 0; int lens = strlen(s);

CCF 字符串匹配

问题描述 试题编号: 201409-3 试题名称: 字符串匹配 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 给出一个字符串和多行文字,在这些文字中找到字符串出现的那些行.你的程序还需支持大小写敏感选项:当选项打开时,表示同一个字母的大写和小写看作不同的字符:当选项关闭时,表示同一个字母的大写和小写看作相同的字符. 输入格式 输入的第一行包含一个字符串S,由大小写英文字母组成. 第二行包含一个数字,表示大小写敏感的选项,当数字为0时表示大小写不敏感,当数字为1时表示大小

字符串匹配的KMP算法

html, body { font-size: 15px; } body { font-family: Helvetica, "Hiragino Sans GB", 微软雅黑, "Microsoft YaHei UI", SimSun, SimHei, arial, sans-serif; line-height: 1.6; color: ; background-color: ; margin: 0; padding: 16px 20px; } h1, h2, h

字符串匹配与KMP算法笔记

>>字符串匹配问题 字符串匹配问题即在匹配串中寻找模式串是否出现, 首先想到的是使用暴力破解,也就是Brute Force(BF或蛮力搜索) 算法,将匹配串和模式串左对齐,然后从左向右一个一个进行比较, 如果不成功则模式串向右移动一个单位,直到匹配成功或者到达匹配串最后仍然不成功,返回失败. 很明显,这种算法有很多的地方可以优化,假设要搜索的串为S,长度为n,要匹配的串为M,长度为m,时间复杂度为O(nm). >>KMP算法 Knuth-Morris-Pratt算法以三个发明者命名

KMP算法解决字符串匹配

该算法由D.E.Knuth ,J.H.Morris和 V.R.Pratt提出,用于解决字符串匹配问题. 思想: 设目标串(主串)为s,模式串为t ,并设i指针和j指针分别指示目标串和模式串中正待比较的字符,设i和j的初值均为0.若有s[i]=t[j],则i和j分别加1.否则,i不变,j退回到j=next[j-1]的位置,再比较s[i]和t[j],若相等,则i和j分别加1.否则,i不变,j再次退回到j=next[j]的位置,依此类推.直到下列两种可能: 1. 模式串t中的字符全部匹配,则出现频率+

字符串匹配 【kmp】

字符串匹配 Time Limit: 1 Sec Memory Limit: 128 MB Submit: 214 Solved: 81 Description 给你两个字符串A,B,请输出B字符串在A字符串中出现了几次. Input 多组测试数据,每组输入两个字符串.字符串的长度 <= 1000000. Output 输出B在A中出现的次数. Sample Input aaa aa Sample Output 1 子串在母串中出现的次数,串不重叠 #include <stdio.h> #

九度机试 题目1165:字符串匹配 2008年北京航空航天大学计算机研究生机试真题

题目1165:字符串匹配 时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:2497 解决:858 题目描述: 读入数据string[ ],然后读入一个短字符串.要求查找string[ ]中和短字符串的所有匹配,输出行号.匹配字符串.匹配时不区分大小写,并且可以有一个用中括号表示的模式匹配.如"aa[123]bb",就是说aa1bb.aa2bb.aa3bb都算匹配. 输入: 输入有多组数据. 每组数据第一行输入n(1<=n<=1000),从第二行开始输入n个字符串(

字符串匹配问题

.字符串匹配问题 [问题描述] 字符串中只含有括号 (),[],<>,{},判断输入的字符串中括号是否匹配.如果括号有互相包含的形式,从内到外必须是<>,(),[],{},例如.输入: [()] 输出:YES,而输入([]), ([])都应该输出NO. [输入格式]strs.in 文件的第一行为一个整数n,表示以下有多少个由括好组成的字符串.接下来的n行,每行都是一个由括号组成的长度不超过255的字符串. [输出格式]strs.out 在输出文件中有N行,每行都是YES或NO. [

【Foreign】字符串匹配 [KMP]

字符串匹配 Time Limit: 10 Sec  Memory Limit: 256 MB Description Input Output Sample Input 3 3 6 3 1 2 1 2 3 2 3 1 3 6 3 1 2 1 2 1 2 3 1 3 6 3 1 1 2 1 2 1 3 1 3 Sample Output 3 1 2 4 4 1 2 3 4 3 2 3 4 HINT Source 发现题目中颜色的具体权值是对答案无关的,然后就是只要相对位置一样即可. 那么显然是一个