具有回调的唯一数组值

时间:2013-09-16 10:39:07

标签: php arrays algorithm complexity-theory

SO,

问题

第一种情况

我有一个带有一些值的数组 - 首先,让它们都是字符串(或者可以简单地视为字符串)。例如:

$rgData = ['foo', 'feo', 'bar', 'baz', 'bee'];

现在,我想从中创建唯一的数组,其中两个项之间的Levenshtein distance小于2。如果$x,则$ylevenshtein($x, $y) < 2项视为相等。例如,foofeo相同,还有barbaz - 但不是barbee

第二种情况

我有一个点坐标为[x, y]的数组,例如:

$rgData = [[0, 0.1], [-5, 4.5], [0, 0.5], [-5.5, 4.5]];

现在,我想从中创建唯一的数组,其中两点之间的距离小于1。如果$x

,则$ypow((pow($x[0]-$y[0], 2) + pow($x[1]-$y[1],2)), 0.5)<1被视为相等

很明显,这两种情况都可以通过某种函数来解决,这种函数类似于标准的PHP array_unique() - 但它接受比较函数来检查项是否相等。我的问题是关于这个功能。

我的方法

现在,我有最简单的解决方案:

function array_uunique($rgData, $fnCompare=null)
{
    if(!isset($fnCompare))
    {
        return array_unique($rgData);
    }
    if(!is_callable($fnCompare))
    {
        return null;
    }
    if(!count($rgData))
    {
        return array();
    }
    $rgResult = array();
    foreach($rgData as $mItem)
    {
        foreach($rgResult as $mTest)
        {
           if(!call_user_func_array($fnCompare, [$mItem, $mTest]))
           {
              continue 2;
           }
        }
        $rgResult[]=$mItem;
    }
    return $rgResult;
}

-it接受回调作为第二个参数,并使用此比较规则返回不等于的元素,即对于levenshtein,所描述的结果将是:

$rgResult = array_uunique(['foo', 'feo', 'bar', 'baz', 'bee'], function($x, $y)
{
   return levenshtein($x, $y)>1; //or !levenshtein($x, $y)<2
});

- 这将导致

array(3) {
  [0]=>
  string(3) "foo"
  [1]=>
  string(3) "bar"
  [2]=>
  string(3) "bee"
}

- 您可以使用this fiddle来测试它。

具体细节信息

如上所述,这是最简单的方式,但它包含2个嵌套的依赖循环。因此,这种构造的复杂性将是O(N^2) - 这很难过 - 并且对我不起作用,特别是如果比较函数操作成本太高 - 因为我将在数据数组中有大量元素(~1E5。 .1E6至少)。

我的问题是 - 如何改善这个?可能还有另一个好的算法吗?或者可能是我的代码可以以某种方式改进?

更新(基于下面的好评):我知道在一般情况下,这样的问题会导致transitive function问题,例如xFy = yFz => xFz - 例如, levenshtein()不具有传递性。因此,整个结果将至少取决于常见情况中的项目顺序(但不仅仅是它) - 现在对我来说这不是问题,因为我确信我的数据顺序和内容(或者,至少,如果barbaz将通过levenshtein比较返回,则不是问题。所以,我的目标是最小化比较次数(因此比较函数是否具有传递性,或者没有任何变化,我认为,因为我想优化甚至重新创建比较算法本身)

1 个答案:

答案 0 :(得分:1)

输入set = {a,b,c,...} matrice,

   a b c . . .
a  1
b  1 1
C  0 0 1
.        1
.          1
.            1

1如果两个元素在同一组中,1s在对角线反射属性,计算olny下三角形couse symetric属性。在第n行,如果找到匹配,则开始与cols比较,放置1,并删除第n列,形成进一步的比较。我希望这是可以理解的。

最坏情况:如果每个组都有一个元素。