特殊的编辑距离

Posted 顾文繁

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了特殊的编辑距离相关的知识,希望对你有一定的参考价值。

在自然语言处理的过程中,经常需要判断一个字符串和另外一个字符串之间的一个相似程度,其中常见的一个指标就是编辑距离,即一个字符串最少经过多少次“增删改”某个字符,可以变为另一个字符串。如“abc”与“ac”的编辑距离为1,是因为在a和c中间“增加”一个b即可。如“abcd”与“axc”的编辑距离为2,是因为把“abcd”的b修改为x,然后再删除d即可,共2次操作。但是在某种场景中,编辑距离定义为词粒度的。比如句子A “I am a coder”与句子B “hello , I am a singer”之间,对于句子A可以通过添加"hello"和符号",", 并替换"coder"为"singer",共3个操作得到句子B。所以可得其基本的编辑距离为3。在本题中,特别地,对于部分词,比如标点符号“, ”、"hello"对于句子语义的影响并不重要,这部分称之为停用词,这部分可以在匹配的过程中被跳过。比如对于句子A “I am a coder”与句子B “hello , I am a singer”,如果加入了停用词的影响,那编辑距离从3降到1。所以目标是可以有选择性地跳过停用词的情况下,问最小的编辑距离是多少。

输入描述:
共3行
第一行为停用词列表,用空格区分
第二行为句子A,所有词可以用空格区分,词数不超过10000
第三行为句子B,所有词可以用空格区分,词数不超过10000

此题是一个动规二维动态规划问题。单词有停用词,所以要开始动规之前需要进行预处理,将两个字符出现的停用词去掉。
动规三部法:

1.明确dp[i][j]的含义,即前A中第i个单词,前B中第j个单词的最小编辑距离。

2.明确转移方程:

当前A第i个单词和B第j个单词的最小编辑距离为:
1.1如果两个词不同,dp[i][j]可能为修改一个单词的最小编辑为dp[i-1][j-1]+1,或者删除A中第i个单词/B中第j个单词所出现的最小编辑距离,他们之间的最小值。
1.2如果两个词相同,dp[i][j] = dp[i-1][j-1],这个很好理解。即忽略当前相同的词,取上个词语的最小编辑距离。

3.初始化

当第0个单词时,无论第0列还是第0行都是其行数(单词数量)。因为,A中0个单词和B中第1,2,3,4,5…单词匹配,需要的最小编辑距离就是1.2,3,4…

C++实现

#include <bits/stdc++.h>
using namespace std;
int main()

    unordered_set<string> stop;
    string word;
    vector<string> A,B;
    while(cin >> word)
    
        stop.insert(word);
        if(cin.get() == '\\n') break;
    
    for(int i = 0;i < 2;i++)
    
        while(cin >> word)
        
            if(stop.count(word)) continue;
            if(i == 0)
                A.push_back(word);
            else
                B.push_back(word);
            if(cin.get() == '\\n') break;
        
    
    int n1 = A.size();
    int n2 = B.size();
    //dp的内涵:dp[i][j] ,A中第i个单词,B中第j个单词的最小编辑距离
    vector<vector<int>> dp(n1+1, vector<int>(n2+1, 0));
    for(int i = 1;i <= n1;i++) dp[i][0] = i;
    for(int i = 1;i <= n2;i++) dp[0][i] = i;
    for(int i = 1;i <= n1;i++)
    
        for(int j = 1;j <= n2;j++)
        
            if(A[i-1] == B[j-1])
                dp[i][j] = dp[i-1][j-1];
            else  // 两个字符串不一致,从 删除A中的当前单词或者删除B中的当前单词,或者调整其中一个单词。
                dp[i][j] = 1 + min(dp[i-1][j-1], min(dp[i-1][j], dp[i][j-1]));
        
    
    cout << dp[n1][n2] << endl;
    return 0;

以上是关于特殊的编辑距离的主要内容,如果未能解决你的问题,请参考以下文章

特殊的编辑距离

特殊的编辑距离

特殊的编辑距离

怎样衡量两个字符串的相似度(编辑距离动态规划求解)

Java之词义相似度计算(语义识别词语情感趋势词林相似度拼音相似度概念相似度字面相似度)

Java之词义相似度计算(语义识别词语情感趋势词林相似度拼音相似度概念相似度字面相似度)