文本相似度计算

思路是:把字符串的字符放入一个字典中,计算他们(相同的个数/开平方(字符串1的个数*字符串2的个数),得到相似度 


比如要比较    "中国" 和  "中"


则字典中存放的是   

          

 
0(第一个字符串)1(存在)1(存在)
1(第二个字符串)1(存在)0(不存在)

计算相同的个数:    计算中字:  [中][0]*[中][1]=1*1=1       计算国字:[国][0]*[国][1]=1*0=0    则相同的个数为:1+0=1


计算字符串1的个数:     [中][0]*[中][0]=1*1=1      [国][0]*[国][0]=1*1=1       则 字符串一的个数为: 1+1=2

计算字符串2的个数:     [中][1]*[中][1]=1*1=1      [国][0]*[国][0]=0*0=0       则 字符串一的个数为: 1+0=1


相似度为: 相同个数/开方(字符串1的个数*字符2的个数)    1/sqrt(2*1)=0.7 



类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace txtSim
{
    class TxtSim
    {
        public static double GetSimilarity(string doc1, string doc2)
        {
            if (doc1 != null && doc1.Trim() != string.Empty &&
                doc2 != null && doc2.Trim() != string.Empty)
            {
                Dictionary<Int16, int[]> algMap = new Dictionary<Int16, int[]>();

                for (int i = 0; i < doc1.Length; i++)
                {
                    if (IsHanZi(doc1[i]))
                    {
                        Int16 chval = GetGB2312Id(doc1[i]);
                        if (chval != -1)
                        {
                            if (algMap.ContainsKey(chval))
                            {
                                algMap[chval][0] += 1;
                            }
                            else
                            {
                                algMap.Add(chval, new int[2]);
                                algMap[chval][0] = 1;
                            }
                        }
                    }
                }

                for (int i = 0; i < doc2.Length; i++)
                {
                    if (IsHanZi(doc2[i]))
                    {
                        Int16 chval = GetGB2312Id(doc2[i]);
                        if (chval != -1)
                        {
                            if (algMap.ContainsKey(chval))
                            {
                                algMap[chval][1] += 1;
                            }
                            else
                            {
                                algMap.Add(chval, new int[2]);
                                algMap[chval][1] = 1;
                            }
                        }
                    }
                }
                // 对比计算
                double rst = 0.0d;
                double sqdoc1 = 0;
                double sqdoc2 = 0;
                double denominator = 0;
                foreach (KeyValuePair<Int16, int[]> kv in algMap)
                {
                    //利用两个都存在时(都为1,1*1=1),一个存在时为(1*0=0),d都不存在时为(0*0=0)求出相同的个数 
                    denominator += kv.Value[0] * kv.Value[1];
                    //求出字符串1的字符个数
                    sqdoc1 += kv.Value[0] * kv.Value[0];
                    //求出字符串2的字符个数
                    sqdoc2 += kv.Value[1] * kv.Value[1];
                }
                rst = denominator / Math.Sqrt(sqdoc1 * sqdoc2);

                return rst;
            }
            else
            {
                return 0.0d;
            }
        }

        public static bool IsHanZi(char ch)
        {
            bool rst = false;

            string tmp = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";

            rst = tmp.IndexOf(ch) > -1;
            if (!rst)
            {
                rst = (ch >= 0x4e00 && ch <= 0x9fa5);
            }
            return rst;
        }

        public static Int16 GetGB2312Id(char ch)
        {
            try
            {
                byte[] buf = Encoding.GetEncoding("GB2312").GetBytes(ch.ToString());

                if (buf.Length != 2)
                {
                    return (Int16)(buf[0] & 0xff);
                }
                int b0 = (int)(buf[0] & 0xff) - 161;
                int b1 = (int)(buf[1] & 0xff) - 161;

                return (Int16)(b0 * 94 + b1);
            }
            catch { }

            return -1;
        }
    }
}

GetGB2312Id主要是把中文改成编号来作为字典标识

比如"中"字编号为20013即 [中][0] 在字典中为[20013][0]


实例:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace txtSim
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            var s = TxtSim.GetSimilarity(this.textBox1.Text.Trim(), this.textBox2.Text.ToString().Trim());
            this.label1.Text = s.ToString();
        }
    }
}










                  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

张小凡vip

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值