使用场景:Google 的 simhash 算法

 //通过大量测试,simhash用于比较大文本,比如500字以上效果都还蛮好,距离小于3的基本都是相似,误判率也比较低。

 //从我的经验,如果我们假定N是每个块的大小,M是重叠的字符的数目,N = 4和M = 3是最好的选择

  

    public class SimHashAnalyser : IAnalyser
{ private const int HashSize = 32; public float GetLikenessValue(string needle, string haystack)
{
var needleSimHash = this.DoCalculateSimHash(needle);
var hayStackSimHash = this.DoCalculateSimHash(haystack);
return (HashSize - GetHammingDistance(needleSimHash, hayStackSimHash)) / (float)HashSize;
} private static IEnumerable<int> DoHashTokens(IEnumerable<string> tokens)
{
var hashedTokens = new List<int>();
foreach (string token in tokens)
{
hashedTokens.Add(token.GetHashCode());
}
return hashedTokens;
} private static int GetHammingDistance(int firstValue, int secondValue)
{
var hammingBits = firstValue ^ secondValue;
var hammingValue = 0;
for (int i = 0; i < 32; i++)
{
if (IsBitSet(hammingBits, i))
{
hammingValue += 1;
}
}
return hammingValue;
} private static bool IsBitSet(int b, int pos)
{
return (b & (1 << pos)) != 0;
} private int DoCalculateSimHash(string input)
{
ITokeniser tokeniser = new OverlappingStringTokeniser(4, 3);
var hashedtokens = DoHashTokens(tokeniser.Tokenise(input));
var vector = new int[HashSize];
for (var i = 0; i < HashSize; i++)
{
vector[i] = 0;
} foreach (var value in hashedtokens)
{
for (var j = 0; j < HashSize; j++)
{
if (IsBitSet(value, j))
{
vector[j] += 1;
}
else
{
vector[j] -= 1;
}
}
} var fingerprint = 0;
for (var i = 0; i < HashSize; i++)
{
if (vector[i] > 0)
{
fingerprint += 1 << i;
}
}
return fingerprint;
} } public interface IAnalyser
{
float GetLikenessValue(string needle, string haystack);
} public interface ITokeniser
{
IEnumerable<string> Tokenise(string input);
} public class FixedSizeStringTokeniser : ITokeniser
{
private readonly ushort tokensize = 5;
public FixedSizeStringTokeniser(ushort tokenSize)
{
if (tokenSize < 2 || tokenSize > 127)
{
throw new ArgumentException("Token 不能超出范围");
}
this.tokensize = tokenSize;
} public IEnumerable<string> Tokenise(string input)
{
var chunks = new List<string>();
int offset = 0;
while (offset < input.Length)
{
chunks.Add(new string(input.Skip(offset).Take(this.tokensize).ToArray()));
offset += this.tokensize;
}
return chunks;
} } public class OverlappingStringTokeniser : ITokeniser
{ private readonly ushort chunkSize = 4;
private readonly ushort overlapSize = 3; public OverlappingStringTokeniser(ushort chunkSize, ushort overlapSize)
{
if (chunkSize <= overlapSize)
{
throw new ArgumentException("Chunck 必须大于 overlap");
}
this.overlapSize = overlapSize;
this.chunkSize = chunkSize;
} public IEnumerable<string> Tokenise(string input)
{
var result = new List<string>();
int position = 0;
while (position < input.Length - this.chunkSize)
{
result.Add(input.Substring(position, this.chunkSize));
position += this.chunkSize - this.overlapSize;
}
return result;
} }

  

使用:

    const string HayStack = "中国香港………………";
const string Needle = "中国香港 2013………………"; IAnalyser analyser = new SimHashAnalyser();
var likeness = analyser.GetLikenessValue(Needle, HayStack); Console.Clear();
Console.WriteLine("Likeness: {0}%", likeness * 100);
Console.ReadKey();

  

SimHash for c#

c#-SimHash匹配相似-算法的更多相关文章

  1. 【HDU 2255】奔小康赚大钱 (最佳二分匹配KM算法)

    奔小康赚大钱 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Subm ...

  2. HDU 5943 Kingdom of Obsession 【二分图匹配 匈牙利算法】 (2016年中国大学生程序设计竞赛(杭州))

    Kingdom of Obsession Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Oth ...

  3. USACO 4.2 The Perfect Stall(二分图匹配匈牙利算法)

    The Perfect StallHal Burch Farmer John completed his new barn just last week, complete with all the ...

  4. 浅谈压缩感知(九):正交匹配追踪算法OMP

    主要内容: OMP算法介绍 OMP的MATLAB实现 OMP中的数学知识 一.OMP算法介绍 来源:http://blog.csdn.net/scucj/article/details/7467955 ...

  5. 匹配追踪算法(MP)简介

    图像的稀疏表征 分割原始图像为若干个\[\sqrt{n} \times \sqrt{n}\]的块. 这些图像块就是样本集合中的单个样本\(y = \mathbb{R}^n\). 在固定的字典上稀疏分解 ...

  6. 全局匹配KMP算法

    KMP算法是通过分析模式字符串,预先计算每个位置发生不匹配的时候,所需GOTO的下一个比较位置,整理出来一个next数组,然后在上面的算法中使用. 本全局匹配KMP算法针对串的堆式存储数据结构 # d ...

  7. 训练指南 UVALive - 4043(二分图匹配 + KM算法)

    layout: post title: 训练指南 UVALive - 4043(二分图匹配 + KM算法) author: "luowentaoaa" catalog: true ...

  8. 二分图最大权匹配——KM算法

    前言 这东西虽然我早就学过了,但是最近才发现我以前学的是假的,心中感慨万千(雾),故作此篇. 简介 带权二分图:每条边都有权值的二分图 最大权匹配:使所选边权和最大的匹配 KM算法,全称Kuhn-Mu ...

  9. 匹配Luhn算法:可用于检测银行卡卡号

    匹配Luhn算法:可用于检测银行卡卡号 /** * http://www.cnblogs.com/JnKindle/p/5798974.html * * 匹配Luhn算法:可用于检测银行卡卡号 * * ...

随机推荐

  1. 关于 error: Operation is not valid due to the current state of the object。

    今天碰到一个特别的异常. Operation is not valid due to the current state of the object. at System.Web.HttpValueC ...

  2. HTML当中特殊字符的表示

    (回车换行) <br> (空格符)   &(AND符号) & <(左尖括号.小于号) < >(右尖括号.大于号) > °(度) ° •(间隔符) • ...

  3. 12.super关键字

    ①在java中使用super关键字来调用父类的成分

  4. NGUI实现技能CD效果

    在NGUI中使用Sprite的遮罩效果可以很轻松的实现技能CD效果. 具体实现步骤: ①新建一个技能图标的Sprite 如图中的Skill001,再在该技能Sprite上添加一个Sprite做遮罩, ...

  5. 巧妙利用before和after伪类实现文字的展开和收起

    需求:一段文字,当收起的时候,显示4行,并且多余4行的部分用省略号表示,关键是在省略号前面留有空白部分来放一些图标等东西:展开的时候,全部显示. 例如下面的示例图: 收起的时候: 展开的时候: 在不用 ...

  6. 安卓中級教程(6):annotation的基本用法

    package com.example.ele_me.activity; import android.annotation.SuppressLint; import android.app.Acti ...

  7. Eclipse导入现有项目

    针对一些新手内容 1.Eclipse 打开一个项目 第一步File-->Import导入 第二步:选择导入类型 第三步选择文件路径,点击Browse... 注意下面细红框选项,根据需要勾选 第四 ...

  8. 一段可以清理NSArray中的空对象的代码(递归)

    - (NSArray *)clearAllNullObject{ NSMutableArray *array = [self mutableCopy]; ;i < array.count;i++ ...

  9. Mac下,使用sshpass让iterm2支持多ssh登录信息保存

    windows里有个Xshell非常的方便好使,因为它能保存你所有的ssh登录帐号信息.MAC下并没有xshell,有些也提供这样的功能,但效果都不好.iterm2是很好的终端,但却不能很好的支持多p ...

  10. phpexcel 导出 科学计数问题

    今天在用php做excel导出的时候遇到了一个小问题,如图 单元格默认格式为常规格式,当数值过长时就会变成科学计数. 解决方法: 如果输出的excel的$data数据是手动添加的,那就在对应值得后面添 ...