C# 文章相似度算法 Levenshtein 编辑距离算法(转)

本文介绍了一种用于计算两个字符串相似度的C#实现方式,即Levenshtein编辑距离算法。通过实例化LevenshteinDistance类,并设置两个字符串属性,可以异步或同步启动计算任务,最终返回两个字符串之间的相似度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

编辑距离的算法是首先由俄国科学家Levenshtein提出的,故又叫 Levenshtein Distance。一个字符串可以通过增加一个字符,删除一个字符,替换一个字符得到另外一个字符串,假设,我们把从字符串A转换成字符串B,前面3种操作所执行的最少次数称为AB相似度
如  abc adc  度为 1
      ababababa babababab 度为 2
      abcd acdb 度为2

下面是C#实现

using System;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace Levenshtein
{
    /// <summary>
    /// 分析完成事件委托
    /// </summary>
    /// <param name="sim">相似度</param>
    public delegate void AnalyzerCompletedHander(double sim);

    /// <summary>
    /// 文章相似度工具
    /// </summary>
    public class LevenshteinDistance:IDisposable
    {
        private string str1;
        private string str2;
        private int[,] index;
        int k;
        Task<double> task;

        /// <summary>
        /// 分析完成事件
        /// </summary>
        public event AnalyzerCompletedHander AnalyzerCompleted;

        /// <summary>
        /// 获取或设置文章1
        /// </summary>
        public string Str1
        {
            get { return str1; }
            set
            {
                str1 = Format(value);
                index = new int[str1.Length, str2.Length];
            }
        }

        /// <summary>
        /// 获取或设置文章2
        /// </summary>
        public string Str2
        {
            get { return str2; }
            set
            {
                str2 = Format(value);
                index = new int[str1.Length, str2.Length];
            }
        }

        /// <summary>
        /// 运算总次数
        /// </summary>
        public int TotalTimes
        {
            get { return str1.Length * str2.Length; }
        }

        /// <summary>
        /// 是否完成
        /// </summary>
        public bool IsCompleted
        {
            get { return task.IsCompleted; }
        }

        /// <summary>
        /// 实例化
        /// </summary>
        /// <param name="str1">文章1</param>
        /// <param name="str2">文章2</param>
        public LevenshteinDistance(string str1, string str2)
        {
            this.str1 = Format(str1);
            this.str2 = Format(str2);
            index = new int[str1.Length, str2.Length];
        }

        public LevenshteinDistance()
        {
        }

        /// <summary>
        /// 异步开始任务
        /// </summary>
        public void Start()
        {
            task = new Task<double>(Analyzer);
            task.Start();
            task.ContinueWith(o => Completed(o.Result));
        }

        /// <summary>
        /// 同步开始任务
        /// </summary>
        /// <returns>相似度</returns>
        public double StartAyns()
        {
            task = new Task<double>(Analyzer);
            task.Start();
            task.Wait();
            return task.Result;
        }

        private void Completed(double s)
        {
            if (AnalyzerCompleted != null)
            {
                AnalyzerCompleted(s);
            }
        }

        private double Analyzer()
        {
            if (str1.Length == 0 || str2.Length == 0)
                return 0;
            for (int i = 0; i < str1.Length; i++)
            {
                for (int j = 0; j < str2.Length; j++)
                {
                    k = str1[i] == str2[j] ? 0 : 1;
                    if (i == 0&&j==0)
                    {
                        continue;
                    }
                    else if (i == 0)
                    {
                        index[i, j] = k + index[i, j - 1];
                        continue;
                    }
                    else if (j == 0)
                    {
                        index[i, j] = k + index[i - 1, j];
                        continue;
                    }
                    int temp = Min(index[i, j - 1],
                        index[i - 1, j],
                        index[i - 1, j - 1]);
                    index[i, j] = temp + k;
                }
            }
            float similarty = 1 - (float)index[str1.Length - 1, str2.Length - 1]
                / (str1.Length > str2.Length ? str1.Length : str2.Length);
            return similarty;
        }

        private string Format(string str)
        {
            str = Regex.Replace(str, @"[^a-zA-Z0-9\u4e00-\u9fa5\s]", "");
            return str;
        }

        private int Min(int a, int b, int c)
        {
            int temp = a < b ? a : b;
            temp = temp < c ? temp : c;
            return temp;
        }

        public void Dispose()
        {
            task.Dispose();
        }
    }
}

如非注明 均属原创 如需转载 都请注明: Alien的博客

本文链接地址: C# 文章相似度算法 Levenshtein 编辑距离算法

转载于:https://www.cnblogs.com/haorensw/archive/2012/05/26/2518868.html

namespace ServiceRanking { /// <summary> /// Summary description for TF_IDFLib. /// </summary> public class TFIDFMeasure { private string[] _docs; private string[][] _ngramDoc; private int _numDocs=0; private int _numTerms=0; private ArrayList _terms; private int[][] _termFreq; private float[][] _termWeight; private int[] _maxTermFreq; private int[] _docFreq; public class TermVector { public static float ComputeCosineSimilarity(float[] vector1, float[] vector2) { if (vector1.Length != vector2.Length) throw new Exception("DIFER LENGTH"); float denom=(VectorLength(vector1) * VectorLength(vector2)); if (denom == 0F) return 0F; else return (InnerProduct(vector1, vector2) / denom); } public static float InnerProduct(float[] vector1, float[] vector2) { if (vector1.Length != vector2.Length) throw new Exception("DIFFER LENGTH ARE NOT ALLOWED"); float result=0F; for (int i=0; i < vector1.Length; i++) result += vector1[i] * vector2[i]; return result; } public static float VectorLength(float[] vector) { float sum=0.0F; for (int i=0; i < vector.Length; i++) sum=sum + (vector[i] * vector[i]); return (float)Math.Sqrt(sum); } } private IDictionary _wordsIndex=new Hashtable() ; public TFIDFMeasure(string[] documents) { _docs=documents; _numDocs=documents.Length ; MyInit(); } private void GeneratNgramText() { } private ArrayList GenerateTerms(string[] docs) { ArrayList uniques=new ArrayList() ; _ngramDoc=new string[_numDocs][] ; for (int i=0; i < docs.Length ; i++) { Tokeniser tokenizer=new Tokeniser() ; string[] words=tokenizer.Partition(docs[i]); for (int j=0; j < words.Length ; j++) if (!uniques.Contains(words[j]) ) uniques.Add(words[j]) ; } return uniques; } private static object
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值