字符串相似度算法及应用

Levenshtein Distance 简介

字符串相似度的算法还是比较经典的DP算法,看到有两篇文章写的比较不错,他们的介绍也非常详细,值得学习。文章地址如下:

文章1 http://blog.csdn.net/orbit/article/details/6649322 (C++) ,

文章2 http://www.cnblogs.com/ivanyb/archive/2011/11/25/2263356.html (C#)。

文章1中实现Levenshtein Distance的算法已经比较简洁了,不过他是在Stack上申请的距离数组,如果处理特别长字符串,会耗尽Stack,所以改为在Heap上申请内存。

//Implement Levenshtein Distance
// author mingspy 5/30 2012
#include "stdafx.h"
#include <iostream>
#include <cmath>

#define Element(arr, col, i, j) arr[(i)*(col)+j]


template<typename T>
inline const T& min(const T& i, const T& j, const T& k)
{
    return std::min(std::min(i, j), k);
}

int LevenshteinDistance(const char * str1, int len1, const char * str2, int len2)
{
    if(!str1 || !str2)
    {
        _ASSERT(false);
        return INT_MAX;
    }

    // new a matrix with [len1, len2] to save result.
    int * distance = new int[(len1+1)*(len2+1)];
    memset(distance, 0, (len1+1)*(len2+1) * sizeof(int));

    // Initialize the matrix first row.
    for(int i = 0; i < len1+1; i++)
    {
        distance[i] = i;
    }

    // Initialize the matrix first column.
    for(int i= 0; i< len2+1; i++)
    {
        distance[(len1+1)*i] = i;
    }

    // Using dynamic programming to calculate 
    // the distance between str1 and str2.
    int dist = 0;
    for(int i = 1; i < len2 + 1; i++)
    {
        for(int j = 1; j < len1 + 1; j++)
        {
            if(str1[j - 1] == str2[i - 1])
            {
                dist = 0;
            }
            else
            {
                dist = 1;
            }

            Element(distance, len1 + 1, i, j) = min(
                Element(distance, len1 + 1, i - 1, j -1) + dist, 
                Element(distance, len1 + 1, i - 1, j) + 1, 
                Element(distance, len1 + 1, i, j-1) + 1);
        }
    }

#ifdef _DEBUG
    // print distance
    for(int i = 0; i < len2 + 1; i++)
    {
        for(int j = 0; j < len1 + 1; j++)
        {
           std::cout<<Element(distance, len1 + 1, i, j)<<" ";
        }
        std::cout<<std::endl;
    }
#endif

    dist = Element(distance,len1 + 1, len2, len1);
    delete [] distance;
    return dist;
}

 

算法中占用(M+1)*(N+1)的额外内存,让人感觉很是浪费,如果能减少内存的使用那么就相当完美了,在CodeProject找到一篇文章,只用了M+N个额外空间:

http://www.codeproject.com/Articles/8265/More-than-strcmp-similarity-in-strings

应用

最后说一下我是在什么地方使用这个算法的。比如有一幅固定大小的图片,在图片上固定位置有比较规则排列的字符,写一个算法提取出这些字符串。

这是一个简单的字符串识别的小程序,不涉及到字符串的形变和噪声(很少噪声)。我的做法就相当简单:

1.定位到图片字符串的位置。

2.剪切字符串所在位置的图片。

3.二值化图片。

4.切割出每个字符。

5.用每个字符的特征串与字符库的特征串进行比较,得出字符串所代表的字符。

 

第5步的比较算法就用到了字符串相识度算法。由于二值化后的图片还可能存在噪声,我又不想使用去噪的算法,所以对切割后的图片,提取特征码之后,采用相似度匹配字符串库,这样就得到了比较理想的结果。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
字符串相似度算法是用来比较两个字符串之间的相似程度的算法。常用的字符串相似度计算方法有编辑距离算法、余弦相似度算法、Jaccard相似度算法等。其中,编辑距离算法是一种常用的字符串相似度计算方法,它通过计算两个字符串之间的最小编辑距离来衡量它们的相似程度。编辑距离指的是将一个字符串转换成另一个字符串所需的最少操作次数,包括插入、删除、替换三种操作。 编辑距离算法的实现可以采用动态规划的方法,具体步骤如下: 1. 初始化一个二维数组,数组的行数为第一个字符串的长度加1,列数为第二个字符串的长度加1。 2. 将第一行和第一列的值分别初始化为0到列数和0到行数。 3. 从第二行和第二列开始,遍历整个二维数组,计算每个位置的值。具体计算方法如下: - 如果第一个字符串的当前字符等于第二个字符串的当前字符,则该位置的值等于左上角位置的值。 - 否则,该位置的值等于左上角、左边、上边三个位置中的最小值加1。 4. 遍历完整个二维数组后,右下角的值即为两个字符串之间的最小编辑距离。 除了编辑距离算法,余弦相似度算法和Jaccard相似度算法也是常用的字符串相似度计算方法。余弦相似度算法通过计算两个向量之间的夹角余弦值来衡量它们的相似程度,适用于文本分类、信息检索等领域。Jaccard相似度算法则通过计算两个集合的交集与并集之间的比值来衡量它们的相似程度,适用于推荐系统、社交网络等领域。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值