C#计算字符串相似性的方法

作者:kevin0216 时间:2022-08-18 11:32:15 

本文实例讲述了C#计算字符串相似性的方法。分享给大家供大家参考。具体如下:

计算字符串相似性的办法很多,甚至最笨的办法可以挨个匹配,这里要讲的是使用莱文史特距离来计算字符串相似性。
莱文史特距离概念:假设函数名是LD

用于计算两个字符串之间的相似度。 譬如有两个字符串A和B。假设以A为基准,那么该算法就是计算把B通过(替换、删除、加字符)等方法变成A需要多少步。

例如:
A=”abcd”, B=”abc”, 那么 LD(A,B)=1,只需在B字符串中插入一个字符那么就完全等于A
 A=”abcd”, B=”abcd”, 那么 LD(A,B)= ,因为这两个货完全相同
 A=”abcd”, B=”abdc”, 那么 LD(A,B)= 1,因为只需把B中”dc”互换位置就等于A了。
A=”fwegwegweg@#2″, B=”ddd*&&%^&”, 那么 LD(A,B)= ????,这个叔真不知道了,要用程序算了。
莱文史特距离计算出来的值越大代表步骤越多,说明两个字符串的相似程度越低。

譬如大家要做个简易的“文章抄袭”判定功能,那么用这个莱文史特距离完全可以实现个初步方法。

算法注释:
1、假设字符串str1的长度为 n,str2 的长度为 m。
   如果 n = 0,则返回 m并退出;(这是句废话)
2、如果 m=0,则返回 n 并退出。(这依然是句废话)
3、如果上述都不是则要开始进行计算,

构建一个数组 d[0..m, 0..n]。
将第0行初始化为 0..n,第0列初始化为0..m。
依次检查 str1 的每个字母(i=1..n)。
依次检查 str2 的每个字母(j=1..m)。
如果 str1[i]=str2[j],则 sign=0;(sign仅仅是个标记,没有任何意思,为了记录相等还是不相等)
如果 str1[i]!=str12[j],则 sign=1。
将 d[i,j] 设置为以下三个值中的最小值:
紧邻当前格上方的格的值加一,即 d[i-1,j]+1
紧邻当前格左方的格的值加一,即 d[i,j-1]+1
当前格左上方的格的值加sign,即 d[i-1,j-1]+sign
重复上述几步直到循环结束。d[n,m]既为最终的值

接下来是用c#写的一款莱文史特距离的实现。


public class LDMaker//搞成一个类看起来专业,
//实际上就是脱裤子放屁,这里使用来文史特距离算法
//用于计算字符串之间的相似性
 {
   char[] str1;
   char[] str2;
   public LDMaker(string s1, string s2)
   {
 //替换掉 所有 数字 为固定数字 数字干扰 太严重
 //这里因人而异,在中文文章的匹配中,数字是干扰很严重
 //的,所以我在某些应用中把数字替换掉了。
 //原因是有的文章之间实际上相似性很高,但是故意在里面加一些数字
 //干扰该函数的执行,让机器看出来两篇文章很不同。一般不需要做如下
 // 步骤
 s1=System.Text.RegularExpressions.Regex.Replace(s1,@"(\d+)","1");
 s2 = System.Text.RegularExpressions.Regex.Replace(s2, @"(\d+)", "1");
 str1 = s1.ToCharArray();
 str2 = s2.ToCharArray();
}
public int GetLD()//这是莱文史特距离的算法实现
{
 try
 {
   int m=str1.Length;
   int n=str2.Length;
   int[,] d = new int[m+1, n+1];
   for (int i = 0; i <= m ; i++)
     d[i, 0] = i;
   for (int i = 0; i <= n ; i++)
     d[0, i] = i;
   for (int i = 1; i <= m; i++)
   {
     for (int j = 1; j <= n; j++)
     {
     d[i,j] = d[i - 1,j - 1] + (str1[i - 1] == str2[j - 1] ? 0 : 1);
     //修改一个字符
      d[i,j] = Math.Min(d[i,j], d[i - 1,j] + 1);
     // 插入一个字符串
     d[i,j] = Math.Min(d[i,j], d[i,j - 1] + 1);
     //删除一个字符
     }
   }
   return d[m, n];
   } catch(//出错返回一个很大值
   {
     return 10000;
   }
  }
}

希望本文所述对大家的C#程序设计有所帮助。

标签:C#,字符串,相似
0
投稿

猜你喜欢

  • 验证本机的excel版本的C#代码

    2021-11-01 07:13:20
  • 深入浅出探索Java分布式锁原理

    2021-12-16 11:58:07
  • Android 使用ViewPager实现左右循环滑动及轮播效果

    2022-10-28 15:23:21
  • 详解Mybatis框架SQL防注入指南

    2023-09-16 02:49:02
  • C# CSV文件读写的实现

    2023-05-24 10:39:07
  • Java thrift服务器和客户端创建实例代码

    2022-01-23 04:38:29
  • Spring自动注入失败的解决方法

    2022-08-13 03:41:31
  • Android设计模式之Builder模式解析

    2022-02-11 20:07:46
  • intellij idea中spring boot properties文件不能自动提示问题解决

    2021-09-24 09:53:46
  • Android 使用地图时的权限请求方法

    2023-08-25 15:02:18
  • Java原生序列化和反序列化代码实例

    2023-10-29 21:46:45
  • Java实现颜色渐变效果

    2023-08-25 11:10:45
  • Android设备间实现蓝牙(Bluetooth)共享上网

    2023-02-21 14:25:36
  • spring事务之事务挂起和事务恢复源码解读

    2023-11-26 18:50:42
  • Java创建和启动线程的两种方式实例分析

    2023-12-05 08:26:59
  • 浅谈一下Java的双亲委派模式

    2021-11-12 02:48:17
  • 解决Java原生压缩组件不支持中文文件名乱码的问题

    2021-07-29 22:39:38
  • Android项目实战之仿网易顶部导航栏效果

    2022-07-14 10:20:51
  • C#使用Matrix执行缩放的方法

    2022-05-03 15:46:58
  • C# http系列之以form-data方式上传多个文件及键值对集合到远程服务器

    2023-03-19 17:28:20
  • asp之家 软件编程 m.aspxhome.com