2014-02-17 59 views
2

我需要这个C#函数转换成T-SQL UDFT-SQL汉明距离函数能够小数/串/ UINT64

我需要从有蜂鸣声距离小于一个数据库中获取所有的行x 此功能只是解决方案的一部分。

这些2个散列CSHARP函数返回40,而T-SQL函数返回52

public static ulong csharp_hamming_distance(ulong hash1, ulong hash2) 
{ 
ulong x = hash1^hash2; 
const ulong m1 = 0x5555555555555555UL; 
const ulong m2 = 0x3333333333333333UL; 
const ulong h01 = 0x0101010101010101UL; 
ulong m4 = 0x0f0f0f0f0f0f0f0fUL; 
x -= (x >> 1) & m1; 
x = (x & m2) + ((x >> 2) & m2); 
x = (x + (x >> 4)) & m4; 
return (x * h01) >> 56; 
} 

我有样,但它并没有给我同样的结果。

create function HammingDistance1(@value1 char(8000), @value2 char(8000)) 
returns int 
as 
begin 
    declare @distance int 
    declare @i int 
    declare @len int 

    select @distance = 0, 
      @i =1, 
      @len = case when len(@value1) > len(@value2) 
         then len(@value1) 
         else len(@value2) end 

    if (@value1 is null) or (@value2 is null) 
     return null 

    while (@i <= @len) 
     select @distance = @distance + 
          case 
          when substring(@value1,@i,1) = substring(@value2,@i,1) 
           then 0 
          when substring(@value1,@i,1) < substring(@value2,@i,1) 
           then CAST(substring(@value2,@i,1) as smallint) - CAST(substring(@value1,@i,1) as smallint) 
          when substring(@value1,@i,1) > substring(@value2,@i,1) 
           then CAST(substring(@value1,@i,1) as smallint) - CAST(substring(@value2,@i,1) as smallint) 
          else 1 end, 
       @i = @i +1 
    return @distance 
end 

任何帮助将apreciated

+0

为什么不把它作为一个CLR UDF来使用呢,大概是以'long'(而不是'ulong')的形式传递值,并使用-3732186444946353715和-3062955324861285838作为输入? –

+0

注意:字符串汉明和二元汉明是不同的;通过我的计算,这两个值之间的字符串汉明*作为字符串*是18 ...你怎么得到52? –

+0

谢谢!如果我没有跑这样 SELECT ID查询FROM InstagramPhoto WHERE dbo.HamDist( 转换(VARCHAR,转换(十进制(32,0),phash)), 转换(VARCHAR,转换(十进制(32,0),15383788748848265778)))<15 其中1字段从数据库填充,我会考虑它。 但我不知道如何在这样的查询中将14714557628763197901转换为值-3732186444946353715。 或将其转换为4 bigints用于此查询 http://stackoverflow.com/questions/4777070/hamming-distance-on-binary-strings-in-sql – Johan

回答

1

在海明计算,整数被视为位。汉明距离是位差的数量,可以计算为两个值的异值中非零位的数量。对于您提供的两个整数,按位海明距离的确为40.

14714557628763197901= 
    1100110000110100100111000011001111001001011100011101000111001101 

15383788748848265778= 
    1101010101111110001100100101110000111010110000000111101000110010 

^= 0001100101001010101011100110111111110011101100011010101111111111 

它是40个非零位。显示的C#只是一个奇妙的数字计算方式。

字符串不是这种情况。在TSQL中,您正在执行字符串汉明,这是经典只是字符不同的位置数量。上这两个值作为字符串执行经典汉明距离给出:

"14714557628763197901" 
"15383788748848265778" 
01111111110111111111 = 18 

特殊照顾示例TSQL代码被执行修正的汉明计算;要获得经典汉明距离,只需删除最后两个when子句。

要在TSQL bigint执行二进制汉明距离会很辛苦,因为TSQL不支持BIGINT位运算。但是,您可以使用整数算术分别在左右两半上执行计算,然后添加它们。唯一棘手的部分是该死的MSB以及对转移的影响。

对小数点执行汉明距离没有明确定义。您需要更具体地了解您的想法。