C# 中如何判断字符串的相似度
|
admin
2023年3月22日 17:12
本文热度 679
|
基于 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;
}
}
}
谢谢浏览!
该文章在 2023/3/22 17:12:50 编辑过