C# 中如何判斷字符串的相似度


基於 F23.StringSimilarity.dll  組件。Github 上可以搜索到該組件。

核心方法:

var l = new Levenshtein();
double tempValue = l.Distance("我是中國人", "我是中國人。"); // 將返回 1

 

下面是我擴展的方法,從一個集合中找到與目標字符串最相似的一個或多個字符串。

比如:["我是中國人", "我是美國人", "我的中國心", "我是中國通"]  ,現在要找到 和 “我是中國” 最接近的字符串(可能有多個)。

如果用我下面的擴展方法。返回值  

SimilarityValue = 1,  SimilarityTargetList = ["我是中國人", "我是中國通"]

 

有需要的請拿走,不謝。

 

using F23.StringSimilarity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Demo
{
    /// <summary>
    /// 相似度結果信息
    /// </summary>
    /// <typeparam name="TSource">源集合的類型</typeparam>
    public class SimilarityResultInfo<TSource>
    {
        /// <summary>
        /// 相似度值。值越小,表示差異越小。等於 1 表示只有一個字符差異。等於 0 表示完全相等。
        /// </summary>
        public double SimilarityValue { get; set; }

        /// <summary>
        /// 相似度等於 1 表示只有一個字符差異,則最接近的可能有一個或多個字符串
        /// </summary>
        public IEnumerable<TSource> SimilarityTargetList { get; set; }
    }

    /// <summary>
    /// IEnumerable的擴展類,擴展了一個名為 Similarity 的方法
    /// </summary>
    public static class EnumerableMethodSimilarityExtension
    {
        /// <summary>
        /// 獲取集合中和目標字符串最相似的集合(備注:比如:相似度等於 1 表示只有一個字符差異,則最接近的可能有一個或多個字符串)
        /// </summary>
        /// <param name="source">源集合</param>
        /// <param name="targetText">目標字符串</param>
        /// <returns>如果 source 沒有元素,則返回 NULL。否則,返回值不為 NULL</returns>
        public static SimilarityResultInfo<string> Similarity(this IEnumerable<string> source, string targetText)
        {
            return Similarity<string>(source, c => c, targetText);
        }

        /// <summary>
        /// 獲取集合中和目標字符串最相似的集合(備注:比如:相似度等於 1 表示只有一個字符差異,則最接近的可能有一個或多個字符串)
        /// </summary>
        /// <typeparam name="TSource">源集合的類型</typeparam>
        /// <param name="source">源集合</param>
        /// <param name="textSelector">源集合要比較的屬性</param>
        /// <param name="targetText">目標字符串</param>
        /// <returns>如果 source 沒有元素,則返回 NULL。否則,返回值不為 NULL</returns>
        public static SimilarityResultInfo<TSource> Similarity<TSource>(this IEnumerable<TSource> source, Func<TSource, string> textSelector, string targetText)
        {
            if (source == null)
            {
                throw new ArgumentNullException("source");
            }
            if (textSelector == null)
            {
                throw new ArgumentNullException("textSelector");
            }
            var l = new Levenshtein(); // 檢查 2 個字符串的相似度。
            double? minStringSimilarityValue = null;
            List<TSource> similarityTargetList = null;
            foreach (var item in source)
            {
                string elementTextValue = textSelector(item);
                if (string.IsNullOrEmpty(elementTextValue))
                {
                    continue;
                }
                double tempValue = l.Distance(elementTextValue, targetText);
                if (!minStringSimilarityValue.HasValue)
                {
                    //說明是第一次比較。http://music.cnblogs.com
                    minStringSimilarityValue = tempValue;
                    similarityTargetList = new List<TSource>() { item };
                    continue;
                }
                if (tempValue < minStringSimilarityValue.Value)
                {
                    minStringSimilarityValue = tempValue;
                    similarityTargetList.Clear();
                    similarityTargetList.Add(item);
                    continue;
                }
                if (tempValue == minStringSimilarityValue.Value)
                {
                    similarityTargetList.Add(item);
                    continue;
                }
            }
            if (!minStringSimilarityValue.HasValue)
            {
                //說明集合是空的
                return null;
            }
            SimilarityResultInfo<TSource> result = new SimilarityResultInfo<TSource>();
            result.SimilarityValue = minStringSimilarityValue.Value;
            result.SimilarityTargetList = similarityTargetList;
            return result;
        }
    }


}

 

 

謝謝瀏覽!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM