php计算海明距离(64位)查找相似文档

本文介绍了一个基于PHP实现的Simhash算法示例。该算法主要用于文本相似度比较,通过计算文本的Simhash值并求取海明距离来评估两段文本的相似度。文章详细展示了Simhash类的构造方法、字符串哈希、Simhash值计算及海明距离计算等功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


<?php
class Simhash {

public $m_hash = null;
public $hashbits = null;
public $code = null;
public $m_hashbits = 64;

public function __construct($code='UTF-8'){
$this->code = $code;
}
public function __toString(){
return strval($this->m_hash);
}

//返回hash值
public function simhash($tokens){
foreach($tokens as $x){
$x = $this->string_hash($x);
for($i=0;$i<$this->m_hashbits;$i++){
$bitmask = gmp_init(1);
gmp_setbit($bitmask, $i);
$bitmask = gmp_sub($bitmask,1);
if (gmp_strval(gmp_and($x,$bitmask)) != "0") $v[$i] += 1;
else $v[$i] -= 1;
}
}
$sum = 0;
for($i=0;$i<$this->m_hashbits;$i++){
if ($v[$i] >= 0){
$num = gmp_init(1);
gmp_setbit($num, $i);
$num = gmp_sub($num,1);
$sum = gmp_add($sum,$num);
}
}
$this->m_hash = gmp_strval($sum);
return $this->m_hash;
}

//求海明距离
public function hamming_distance($hash1,$hash2){
$hash1 = strval($hash1);
$hash2 = strval($hash2);
$a = gmp_init($hash1);
$b = gmp_init($hash2);
$c = gmp_init(1);
gmp_setbit($c, $this->m_hashbits);
$c = gmp_sub($c,2);
$x = gmp_and(gmp_xor($a,$b),$c);
$tot = 0;
while(gmp_strval($x)){
$tot += 1;
$x = gmp_and($x,gmp_sub($x,1));
}
return $tot;
}

public function string_hash($source){
if(empty($source)) return 0;
else{
$x = $this->utf8_unicode(mb_substr($source,0,1,$this->code)) << 7;
$m = 1000003;
$mask = gmp_sub(gmp_pow("2", $this->m_hashbits),1);
$len = mb_strlen($source,$this->code);
for($i=0;$i<$len;$i++){
$x = gmp_and(gmp_xor(gmp_mul($x,$m),$this->utf8_unicode(mb_substr($source,$i,1,$this->code))),$mask);
}
$x = gmp_xor($x,$len);
if(intval(gmp_strval($x)) == -1) $x = -2;
return $x;
}
}
function utf8_unicode($c) {
switch(strlen($c)) {
case 1:
return ord($c);
case 2:
$n = (ord($c[0]) & 0x3f) << 6;
$n += ord($c[1]) & 0x3f;
return $n;
case 3:
$n = (ord($c[0]) & 0x1f) << 12;
$n += (ord($c[1]) & 0x3f) << 6;
$n += ord($c[2]) & 0x3f;
return $n;
case 4:
$n = (ord($c[0]) & 0x0f) << 18;
$n += (ord($c[1]) & 0x3f) << 12;
$n += (ord($c[2]) & 0x3f) << 6;
$n += ord($c[3]) & 0x3f;
return $n;
}
}

function dec_to_bin($dec='') {
$bin = '';
if($this->is_64bit()){
$bin = decbin(intval($dec));
}
else{
while ($dec) {
$m = bcmod($dec, 2);
$dec = bcdiv($dec, 2);
$bin .= abs($m);
}
$bin = strrev($bin);
}
if(strlen($bin)<$this->m_hashbits)$bin = str_pad($bin,$this->m_hashbits,"0",STR_PAD_LEFT);
unset($dec);unset($m);
return $bin;
}
function bin_to_dec($input='') {
if($this->is_64bit()){
$output = bindec($input);
}
else{
$output='0';
if(preg_match("/^[01]+$/",$input)) {
for($i=0;$i<strlen($input);$i++)
$output=bcadd(bcmul($output,'2'),$input{$i});
}
if(strpos($output,'.')!==false){
$arr = explode('.',$output);
$output = $arr[0];
}
}
return($output);
}
function is_64bit() {
return false;
}

}

?>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

walk walk

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

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

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

打赏作者

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

抵扣说明:

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

余额充值