句子的编辑距离

在机器翻译中,有时候要做句子的相似度比对,其中要用到编辑距离的计算。而网络上搜索到的资料大部分都将字符作为编辑距离计算的最小单位。事实上,对于句子来说,词语作为编辑距离的最小计算单位往往更加合理。通过动态规划的方法,我们能轻松实现编辑距离的计算。

这里要注意的是递推边界的问题。就是当待译句子移动完之后,会出现0-0,0-1,…,0-n的情况(n为候选句子包含词语的个数),这种情况下需要修改的次数我们可以知道分别是,0,1,….,n。同理假如候选句子经过删除之后,长度剩余为0,那么会出现0-0,1-0,2-0,…,m-0的匹配情况(m为待译句子包含词语的个数),这种情形下,修改次数为0,1,…,m。

因此在算法的开始要做一个数组的初始化,初始化这些已知的操作次数结果。

下面的代码中,我尝试写了递归和非递归的方法。

EditDistanceReverse是递归,EditDistance是非递归的方法。对于中文句子来说最好加入自定义的分词算法。理由我在一开始也说过了。

// EditDistance.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include<string>
#include<iostream>
#include<vector>
using namespace std ;
int dist[100][100];
int EditDistance(const string pattern[], int pattern_size, const string candidate[], int candidate_size)
{
    int r1 = 0;
    int r2 = 0;
    int r3 = 0;
    int i,j;

    //因为0-0编辑距离为0,0-1为1,依次类推
    for(i = 0; i <= candidate_size; i++)
        dist[0][i] = i;

    for(i = 0; i <= pattern_size; i++)
        dist[i][0] = i;

    for (i = 1; i <= pattern_size; i++)
    {
        for (j = 1; j <= candidate_size; j++)
        {

            r1 = dist[i - 1][j] + 1;//删除
            r2 = dist[i][j - 1] + 1;//插入

            int delta = (pattern[i - 1] != candidate[j - 1] ? 1 : 0);
            r3 = dist[i-1][j - 1] + delta;

            int min = r1;
            min = min > r2 ? r2 : min;
            min = min > r3 ? r3 : min;
            dist[i][j] = min;

        }
    }

    return dist[pattern_size][candidate_size];
}

int EditDistanceCore(const string pattern[], int pattern_size, const string candidate[], int candidate_size)
{

    int r1 = 0;
    int r2 = 0;
    int r3 = 0;
    int i,j;

    if(pattern_size == 0 || candidate_size == 0)
        return  dist[pattern_size][candidate_size];

    if (!dist[pattern_size - 1][candidate_size])
        dist[pattern_size - 1][candidate_size] = EditDistanceCore(pattern, pattern_size - 1, candidate, candidate_size);
    r1 = dist[pattern_size - 1][candidate_size] + 1;//删除

    if (!dist[pattern_size][candidate_size - 1])
        dist[pattern_size][candidate_size - 1] = EditDistanceCore(pattern, pattern_size, candidate, candidate_size - 1);
    r2 = dist[pattern_size][candidate_size - 1] + 1;//插入

    int delta = (pattern[pattern_size - 1] != candidate[candidate_size - 1] ? 1 : 0);

    if(!dist[pattern_size - 1][candidate_size - 1])
        dist[pattern_size - 1][candidate_size - 1] = EditDistanceCore(pattern, pattern_size-1, candidate, candidate_size - 1);

    r3 = dist[pattern_size - 1][candidate_size - 1] + delta;

    int min = r1;
    min = min > r2 ? r2 : min;
    min = min > r3 ? r3 : min;  

    dist[pattern_size][candidate_size] = min;
    return min;
}
int EditDistanceReverse(const string pattern[], int pattern_size, const string candidate[], int candidate_size)
{
    int i,j;

    //因为0-0编辑距离为0,0-1为1,依次类推
    for(i = 0; i <= candidate_size; i++)
        dist[0][i] = i;

    for(i = 0; i <= pattern_size; i++)
        dist[i][0] = i;

    return EditDistanceCore(pattern, pattern_size, candidate, candidate_size);

}
int _tmain(int argc, _TCHAR* argv[])
{

    string pattern[] ={"I","love","baby","me2"};
    string candidate[] = { "I","love","me"};

    cout << EditDistanceReverse(pattern, sizeof(pattern)/sizeof(string), candidate, sizeof(candidate)/sizeof(string));
    //cout << EditDistance(pattern, sizeof(pattern)/sizeof(string), candidate, sizeof(candidate)/sizeof(string));
    return 0;
}

时间: 2024-11-05 11:30:06

句子的编辑距离的相关文章

nlp自然语言处理中句子相似度计算

在做自然语言处理的过程中,现在智能对话比较火,例如智能客服,智能家电,智能音箱等,我们需要获取用户说话的意图,方便做出正确的回答,这里面就涉及到句子相似度计算的问题,那么本节就来了解一下怎么样来用 Python 实现句子相似度的计算. 句子相似度常用的几种方法: 1.编辑距离 2.杰卡德系数计算 3.Word2Vec 计算 编辑距离,英文叫做 Edit Distance,又称 Levenshtein 距离,是指两个字串之间,由一个转成另一个所需的最少编辑操作次数, 如果它们的距离越大,说明它们越

使用 TF-IDF 加权的空间向量模型实现句子相似度计算

使用 TF-IDF 加权的空间向量模型实现句子相似度计算 字符匹配层次计算句子相似度 计算两个句子相似度的算法有很多种,但是对于从未了解过这方面算法的人来说,可能最容易想到的就是使用字符串匹配相关的算法,来检查两个句子所对应的字符串的字符相似程度.比如单纯的进行子串匹配,搜索 A 串中能与 B 串匹配的最大子串作为得分,亦或者用比较常见的最长公共子序列算法来衡量两个串的相似程度,使用编辑距离算法来衡量等. 上述基于字符匹配层次的算法一定程度上都可以计算出两个句子的相似度,不过他们只是单纯的从字符

最短编辑距离算法

一般情况下,电商在当客户输入一个不存在的商品时,会返回客户一个与客户输入最为接近的商品,并加以提示"您是不是在找XXX?".这其中用到了一种算法,叫做"最短编辑距离算法",能在一大堆已存在的字符串中找到与原字符串最为接近的那个字符串,称之为最短编辑距离. 这种算法是基于动态规划思想,下面是算法的思路描述: 描述: 设A和B是2个字符串.要用最少的字符操作将字符串A转换为字符串B.这里所说的字符操作包括: (1)删除一个字符; (2)插入一个字符: (3)将一个字符改

POJ 3356 AGTC 最短编辑距离 DP

http://poj.org/problem?id=3356 题意: 给两个长度不大于1000的串,修改其中一个串使得两串相同,问最少修改次数.修改有三种,插入一个字符,删除一个字符,改变一个字符. 分析: 直接给方程. dp[i][j]表示第一个串前i位和第二串前j位匹配的最小修改次数. dp[0][0] = 0, dp[length(x)][length(y)]为答案. dp[i][j] = min(dp[i-1][j-1] + x[i] != y[j], dp[i-1][j] + 1, d

poj4323 最短编辑距离

AGTC Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 12240   Accepted: 4594 Description Let x and y be two strings over some finite alphabet A. We would like to transform x into y allowing only operations given below: Deletion: a letter

编辑距离算法(Levenshtein)

编辑距离定义: 编辑距离,又称Levenshtein距离,是指两个字串之间,由一个转成另一个所需的最少编辑操作次数. 许可的编辑操作包括:将一个字符替换成另一个字符,插入一个字符,删除一个字符. 例如将eeba转变成abac: eba(删除第一个e) aba(将剩下的e替换成a) abac(在末尾插入c) 所以eeba和abac的编辑距离就是3 俄罗斯科学家Vladimir Levenshtein在1965年提出这个概念. 算法: 算法就是简单的线性动态规划(最长上升子序列就属于线性动态规划).

POJ 3356 AGTC(DP求字符串编辑距离)

给出两个长度小于1000的字符串,有三种操作,插入一个字符,删除一个字符,替换一个字符. 问A变成B所需的最少操作数(即编辑距离) 考虑DP,可以用反证法证明依次从头到尾对A,B进行匹配是不会影响答案的 令dp[i][j]表示A[i]~[lenA]变成B[j]~[lenB]的最优解. 如果把B[j]插入到A[i]前,dp[i][j]=dp[i][j+1]+1 如果删除A[i],dp[i][j]=dp[i+1][j]+1. 如果A[i]==B[j], dp[i][j]=dp[i+1][j+1].

[LeetCode] One Edit Distance 一个编辑距离

Given two strings S and T, determine if they are both one edit distance apart. 这道题是之前那道Edit Distance的拓展,然而这道题并没有那道题难,这道题只让我们判断两个字符串的编辑距离是否为1,那么我们只需分下列三种情况来考虑就行了: 1. 两个字符串的长度之差大于1,那么直接返回False 2. 两个字符串的长度之差等于1,那么长的那个字符串去掉一个字符,剩下的应该和短的字符串相同 3. 两个字符串的长度之

计算句子相似度

计算编辑距离 # -*- coding: utf-8 -*- def distacal(s1,s2):#计算编辑距离 m = len(s1) n = len(s2) colsize, matrix = m + 1, [] for i in range((m + 1) * (n + 1)): matrix.append(0) for i in range(colsize): matrix[i] = i for i in range(n + 1): matrix[i * colsize] = i f