c#-SimHash匹配相似-算法
使用场景: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();
c#-SimHash匹配相似-算法的更多相关文章
- 【HDU 2255】奔小康赚大钱 (最佳二分匹配KM算法)
奔小康赚大钱 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Subm ...
- HDU 5943 Kingdom of Obsession 【二分图匹配 匈牙利算法】 (2016年中国大学生程序设计竞赛(杭州))
Kingdom of Obsession Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Oth ...
- USACO 4.2 The Perfect Stall(二分图匹配匈牙利算法)
The Perfect StallHal Burch Farmer John completed his new barn just last week, complete with all the ...
- 浅谈压缩感知(九):正交匹配追踪算法OMP
主要内容: OMP算法介绍 OMP的MATLAB实现 OMP中的数学知识 一.OMP算法介绍 来源:http://blog.csdn.net/scucj/article/details/7467955 ...
- 匹配追踪算法(MP)简介
图像的稀疏表征 分割原始图像为若干个\[\sqrt{n} \times \sqrt{n}\]的块. 这些图像块就是样本集合中的单个样本\(y = \mathbb{R}^n\). 在固定的字典上稀疏分解 ...
- 全局匹配KMP算法
KMP算法是通过分析模式字符串,预先计算每个位置发生不匹配的时候,所需GOTO的下一个比较位置,整理出来一个next数组,然后在上面的算法中使用. 本全局匹配KMP算法针对串的堆式存储数据结构 # d ...
- 训练指南 UVALive - 4043(二分图匹配 + KM算法)
layout: post title: 训练指南 UVALive - 4043(二分图匹配 + KM算法) author: "luowentaoaa" catalog: true ...
- 二分图最大权匹配——KM算法
前言 这东西虽然我早就学过了,但是最近才发现我以前学的是假的,心中感慨万千(雾),故作此篇. 简介 带权二分图:每条边都有权值的二分图 最大权匹配:使所选边权和最大的匹配 KM算法,全称Kuhn-Mu ...
- 匹配Luhn算法:可用于检测银行卡卡号
匹配Luhn算法:可用于检测银行卡卡号 /** * http://www.cnblogs.com/JnKindle/p/5798974.html * * 匹配Luhn算法:可用于检测银行卡卡号 * * ...
随机推荐
- 关于 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 ...
- HTML当中特殊字符的表示
(回车换行) <br> (空格符) &(AND符号) & <(左尖括号.小于号) < >(右尖括号.大于号) > °(度) ° •(间隔符) ...
- 12.super关键字
①在java中使用super关键字来调用父类的成分
- NGUI实现技能CD效果
在NGUI中使用Sprite的遮罩效果可以很轻松的实现技能CD效果. 具体实现步骤: ①新建一个技能图标的Sprite 如图中的Skill001,再在该技能Sprite上添加一个Sprite做遮罩, ...
- 巧妙利用before和after伪类实现文字的展开和收起
需求:一段文字,当收起的时候,显示4行,并且多余4行的部分用省略号表示,关键是在省略号前面留有空白部分来放一些图标等东西:展开的时候,全部显示. 例如下面的示例图: 收起的时候: 展开的时候: 在不用 ...
- 安卓中級教程(6):annotation的基本用法
package com.example.ele_me.activity; import android.annotation.SuppressLint; import android.app.Acti ...
- Eclipse导入现有项目
针对一些新手内容 1.Eclipse 打开一个项目 第一步File-->Import导入 第二步:选择导入类型 第三步选择文件路径,点击Browse... 注意下面细红框选项,根据需要勾选 第四 ...
- 一段可以清理NSArray中的空对象的代码(递归)
- (NSArray *)clearAllNullObject{ NSMutableArray *array = [self mutableCopy]; ;i < array.count;i++ ...
- Mac下,使用sshpass让iterm2支持多ssh登录信息保存
windows里有个Xshell非常的方便好使,因为它能保存你所有的ssh登录帐号信息.MAC下并没有xshell,有些也提供这样的功能,但效果都不好.iterm2是很好的终端,但却不能很好的支持多p ...
- phpexcel 导出 科学计数问题
今天在用php做excel导出的时候遇到了一个小问题,如图 单元格默认格式为常规格式,当数值过长时就会变成科学计数. 解决方法: 如果输出的excel的$data数据是手动添加的,那就在对应值得后面添 ...