文字编辑距离代码实现

参考资料:自动化所老师宗成庆老师的《自然语言理解》课程

1、在使用word的时候,输入英文会自动检测出单词是否正确,在单词不正确(字典中查不到的时候),还会给出相应的建议单词。这个功能是如何实现的呢?首先引入一个概念叫做英语单词拼写检查,设X为拼写错误的字符串,长度为m,Y为X对应的正确的单词,其长度为n,则X和Y的编辑距离,定义为:从字符串X到字符串Y需要的插入、删除、替换和交换两个相邻的基本单位的最小个数。


2、算法过程

(1)对于X来说,选取前i个字符,去和Y作距离的计算,max(1,n-t)<=i<=min(m,n+t),t是一个阙值,限定编辑距离和确定截取X的范围。

(2)递归计算ed

(2.0)递归出口:递归到某一个串长度为0,返回另一个串d长度


(2.1)如果两个串最后一个字母相同,则比较去掉最后一个字母的串

ed(X[i+1],Y[j+1]) = ed(X[i],Y[j])

(2.2)如果最后两个字母互换位置之后可以变成相同的串,就交换位置

if(X[i+1]==Y[i]&&X[i]==Y[i+1]),ed(X[i+1],Y[i+1])=1+min{ed(X[i-1],Y[j-1]),ed(X[i],Y[j+1]),ed(X[i+1],Y[j])}

三种情况分别表示,直接交换的,X去掉一个字母相等的,X加上一个字母相等的。

(2.3)其他情况下,就是最后1个字母不相等并且也不交换位置能得到的

ed(X[i+1],Y[i+1])=1+min{ed(X[i],Y[j]),ed(X[i],Y[j+1]),ed(X[i+1],Y[j])}

表示替换最后一个字母,X去掉一个字母相等的,X加上一个字母相等的。


(3)对于每个距离,找出最小的ed值,对应的单词长度就是最小编辑距离。

3、代码实现

其实代码实现就很简单啦,只需要把上面的步骤实现就可以了。这里为了更加直观,只计算出了每个i长度单词的ed距离,没有实现(3)中的功能。注意递归边界和下标越界的情况

计算两个单词的编辑距离python代码:

#!/usr/bin/python
t = 2
s = raw_input("input string:")
p = raw_input("input pattern:")
m = len(s)
n = len(p)
l = max(1,n-t)
u = min(m,n+t)

def ed(i,j):
	dis = 0
#	for k in range(0,i+1):
#		print s[k],
#	print

	if i==0:
		return j
	elif j ==0:
		return i
	elif i==-1 or j==-1:
		return max(m,n)
	elif s[i]==p[j]:
		return ed(i-1,j-1)
	elif i>=1 and s[i-1]==p[j] and s[i]==p[j-1]:
		return 1+min(ed(i-2,j-2),min(ed(i-1,j),ed(i,j-1)))
	elif s[i]!=p[j] and (s[i-1]!=p[j] or s[i]!=p[j-1]):
		return 1+min(ed(i-1,j-1),min(ed(i-1,j),ed(i,j-1)))
	#print s[j],
	#print 

for i in range(l-1,u):
	print ed(i,n-1),

	

#a = int(raw_input("input a:"))
#b = int(raw_input("input b:"))
#print min(a,b)

代码运行结果

input string:reprter             
input pattern:repo
2 1 1 2 3

repr 和 rep代表这距离repo最近的字符串



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是Python代码实现: ```python import numpy as np from scipy.spatial.distance import cosine # 简体汉字Unicode编码范围 Simplified_Chinese_Range = [ (0x4E00, 0x9FFF), # 基本汉字 (0x3400, 0x4DBF), # 扩展A (0x20000, 0x2A6DF), # 扩展B (0x2A700, 0x2B73F), # 扩展C (0x2B740, 0x2B81F), # 扩展D (0x2B820, 0x2CEAF), # 扩展E (0xF900, 0xFAFF), # 兼容汉字 (0x2F800, 0x2FA1F) # 兼容扩展 ] # 繁体汉字Unicode编码范围 Traditional_Chinese_Range = [ (0x4E00, 0x9FFF), # 基本汉字 (0x3400, 0x4DBF), # 扩展A (0x20000, 0x2A6DF), # 扩展B (0x2A700, 0x2B73F), # 扩展C (0x2B740, 0x2B81F), # 扩展D (0x2B820, 0x2CEAF), # 扩展E (0xF900, 0xFAFF), # 兼容汉字 (0x2F800, 0x2FA1F), # 兼容扩展 (0x20000, 0x2A6DF) # 扩展F ] # 多国文字Unicode编码范围 Multilingual_Range = [ (0x0E00, 0x0E7F), # 泰文 (0x0900, 0x097F), # 印地文 (0x0980, 0x09FF), # 孟加拉文 (0x0A00, 0x0A7F), # 古吉拉特文 (0x0A80, 0x0AFF), # 旁遮普文 (0x0B00, 0x0B7F), # 奥里亚文 (0x0B80, 0x0BFF), # 波斯尼亚文 (0x0C00, 0x0C7F), # 泰米尔文 (0x0C80, 0x0CFF), # 卡纳达文 (0x0D00, 0x0D7F), # 马拉雅拉姆文 (0x0D80, 0x0DFF), # 奥克兰文 (0x10A0, 0x10FF), # 格鲁吉亚文 (0x1E00, 0x1EFF), # 拉丁文扩展附加 (0x1F00, 0x1FFF), # 希腊文扩展 (0x2C60, 0x2C7F), # 拉丁文扩展C (0x2D00, 0x2D2F), # 格鲁吉亚文补充 (0xA640, 0xA69F), # 古彼尔姆文 (0xA720, 0xA7FF), # 切罗基文 (0xAA00, 0xAA5F), # 布吉文 (0xAB00, 0xAB2F), # 塔纳文 (0x1200, 0x137F), # 埃塞俄比亚语扩展A (0x1380, 0x139F), # 埃塞俄比亚语扩展B (0x2D30, 0x2D7F), # 提非纳文 (0x2D80, 0x2DDF), # 胡里奥文 ] # 计算KL距离 def KL_distance(p, q): p = np.asarray(p, dtype=np.float) q = np.asarray(q, dtype=np.float) return np.sum(np.where(p != 0, p * np.log(p / q), 0)) # 判断字符是否属于Unicode编码范围 def is_unicode(char, unicode_range): return any(start <= ord(char) <= end for start, end in unicode_range) # 判断字符串是否为简体汉字 def is_simplified_chinese(string): for char in string: if not is_unicode(char, Simplified_Chinese_Range): return False return True # 判断字符串是否为繁体汉字 def is_traditional_chinese(string): for char in string: if not is_unicode(char, Traditional_Chinese_Range): return False return True # 判断字符串是否为多国文字 def is_multilingual(string): for char in string: if not is_unicode(char, Multilingual_Range): return False return True # 示例 text = "这是一段简体中文。這是一段繁體中文。This is some text in English." simplified_chinese_text = "这是一段简体中文。" traditional_chinese_text = "這是一段繁體中文。" multilingual_text = "これは日本語のテキストです。" # 计算KL距离 simplified_chinese_kl = KL_distance([1 / len(simplified_chinese_text)] * len(simplified_chinese_text), [1 / len(text)] * len(text)) traditional_chinese_kl = KL_distance([1 / len(traditional_chinese_text)] * len(traditional_chinese_text), [1 / len(text)] * len(text)) multilingual_kl = KL_distance([1 / len(multilingual_text)] * len(multilingual_text), [1 / len(text)] * len(text)) # 判断字符串属于哪种语言类型 if simplified_chinese_kl < traditional_chinese_kl and simplified_chinese_kl < multilingual_kl: print("这是简体中文。") elif traditional_chinese_kl < simplified_chinese_kl and traditional_chinese_kl < multilingual_kl: print("这是繁体中文。") else: print("这是多国文字。") ``` 以上代码实现了识别一段文字是简体汉语还是繁体汉语和多国文字,利用KL距离实现。其中,通过判断字符是否属于Unicode编码范围来判断字符串是否为简体汉字、繁体汉字或者多国文字。KL距离是用来计算两个概率分布之间的差异,可以用来比较字符分布与文本分布之间的差异。最后,根据计算出来的KL距离来判断字符串属于哪种语言类型。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值