Algorithm 比较“的两个数字”;“相似性”;

Algorithm 比较“的两个数字”;“相似性”;,algorithm,math,pattern-matching,matching,Algorithm,Math,Pattern Matching,Matching,这是网站搜索功能的一部分。因此,我正试图找到一种方法,尽快达到最终结果 有一个二进制数,数字顺序很重要 输入编号=01001 拥有一个由相同长度的其他二进制数组成的数据库 0100010100000011111 我不知道怎么写我在做什么,所以我会在下面更形象地写 // Zeros mean nothing & the location of a 1 matters, not the total number of 1's. input num > 0 1 0 0 1 = 2

这是网站搜索功能的一部分。因此,我正试图找到一种方法,尽快达到最终结果

有一个二进制数,数字顺序很重要

输入编号=01001

拥有一个由相同长度的其他二进制数组成的数据库

0100010100000011111

我不知道怎么写我在做什么,所以我会在下面更形象地写

// Zeros mean nothing & the location of a 1 matters, not the total number of 1's.    
input num > 0 1 0 0 1 = 2 possible matches
number[1] > 0 1 0 0 0 = 1 match = 50% match
number[2] > 1 0 1 1 0 = 0 match = 0% match
number[3] > 0 0 0 0 0 = 0 match = 0% match
number[4] > 1 1 1 1 1 = 2 match = 100% match
很明显,你可以一个数字一个数字地比较(使用循环什么的)。但我希望有一个算法或其他东西能帮上忙。主要是因为在上面的示例中,我只使用了5位数字。但是我会经常比较10万个左右的数字,每个数字有200个数字,这需要大量的计算


我通常处理php和MySQL。但是,如果发生了什么惊人的事情,我总是可以学习的。

假设输入的数字是A(在你的例子中是A=01001),另一个数字是x。当
x&A==A
时,您将有100%的匹配。否则,对于部分匹配,1位的数量将是(取自hacker's delight):


请注意,这适用于32位整数。

假设您有一个函数
bit1count
,那么根据您的描述,“相似性”公式应该是:

100.0 / min(bit1count(n1), bit1count(n2)) * bit1count(n1 & n2)
其中,
n1
n2
是两个数字,
&
是逻辑and运算符

bit1count
可以使用循环轻松实现,或者更优雅地使用BigBears answer中提供的算法

mysql中实际上有一个
BIT\u COUNT
,所以类似的东西应该可以工作:

SELECT 100.0 / IF(BIT_COUNT(n1) < BIT_COUNT(n2), BIT_COUNT(n1), BIT_COUNT(n2)) * BIT_COUNT(n1 & n2) FROM table
从表中选择100.0/IF(位计数(n1)
嗯,我能想到的第一件事是两个数字之间简单的按位AND;然后,您可以分析结果以获得匹配百分比:

if( result >= input ) 
    //100% match
else {
    result ^= input;

    /* The number of 1's in result is the number of 1 of "input" 
     * that are missing in "result".
     */
}

当然,您需要实现自己的AND和XOR函数(这只适用于32位整数)。请注意,它仅适用于无符号数字。

您可以预处理输入并确定哪些位需要检查,而不是检查每个位。在最坏的情况下,这将转移到处理每个位,但对于正态分布,您将节省一些处理

也就是说,用于输入

01001
,迭代数据库并确定
number1[0]&input
是否为非零,
(number1[3]>>8)&input
是否为非零,假设0是LSB的索引。然而,如何获得快速的位移位和和大数的anding取决于您。如果在输入中检测到1s大于0s,则始终可以反转输入并测试零以检测覆盖率


这将给您带来适度的改善,但充其量只是不断减少问题的时间。如果您的大多数输入在0和1之间平衡,则所需操作的数量将减半。如果有更多的偏差,你会得到更好的结果。

如果有可能以某种方式将你的位字符串分割成整数大小的块,一些基本的布尔运算就可以了,而这种指令通常相当快

$matchmask = ~ ($inputval ^ $tomatch) & $inputval
它的作用是:

  • 异或确定inputval和tomatch中不同的位
  • 求反给出一个值,其中设置了inputval和tomatch中相等的所有位
  • 对于inputval,只有inputval和tomatch中的1位保持设置

然后计算结果中设置的位数,寻找最佳解决方案,轻松转换为php

对于任何二进制数,位数的顺序都不重要吗?除此之外,你能解释一下你想要完成什么吗?我不太明白整个计划的目的。只是我头脑中的一个想法,为什么不从比较数字之间的关系开始,比如X>Z,X=不是100%匹配的情况。1s封面,所以它是100%匹配。考虑10000和01111。这是0%匹配,考虑到OPs描述对不起,我不明白你的反对意见。我能想到的唯一问题是,第一个1可能是一个符号数字(添加了一个注释来强调这一点)。根据OPs说明,10000和01111为0%匹配。根据我的代码:
result=input和firstNumber=00000<10000
(想想unsignednumber),所以它是else语句<代码>结果^=输入=>
result=10000
。结果中的1个数是结果中缺少的
输入
中的1个数。啊,这在文本中不清楚。我直接去了
$matchmask = ~ ($inputval ^ $tomatch) & $inputval