用于检测匹配的高效算法

时间:2010-01-15 02:46:46

标签: php algorithm performance

我正在寻找一种有效的算法来检测整数N大小的数组中的相等值。它必须返回匹配的索引。

唉,我想不出比两个循环更强大的蛮力。

任何帮助将不胜感激。 谢谢!

7 个答案:

答案 0 :(得分:2)

你可以与数组相交。这将查找array1

中array2的所有值
$array1 = array("a" => "green", "b" => "brown", "c" => "blue", "red");
$array2 = array("a" => "green", "yellow", "red");
$result_array = array_intersect_assoc($array1, $array2);
print_r($result_array);

会返回

Array
(
    [a] => green
)

它返回一个包含匹配项的所有键和值的数组。基本上,您可以为array_insert_assoc提供无限数量的参数:

array_intersect_assoc($base_array, $arr1, $arr2 ...);

它将在$base_array中搜索所有后续数组中的值。这意味着密钥和值将取自$base_array

您还可以使用以下方法比较密钥:

array_intersect_keys($base_array, $arr1, $arr2, $arr3);

答案 1 :(得分:1)

这些循环是O(N ^ 2)。 N大吗?如果是这样,你可以对数组O(NlogN)进行排序,然后将其扫描为O(N)吗? ......或者我错过了什么?

答案 2 :(得分:1)

您可以使用一组来保存最近的值。例如,

results = empty list
set = empty set
foreach key, val in array:
   if val is not in set: add val to set
   else: add key to results
return results

每次查找集都是O(1),因此如果使用嵌套循环,这个算法将导致O(n)而不是O(n ^ 2)。

如果你想跟踪像这个数组1, 2, 3, 3, 2, 1这样的多次出现,你可以使用带键的哈希表,值和值(表中相应键的值)是索引列表。给定数组的结果看起来像{1:0,5; 2:1,4; 3:2,3}。

results = empty hashtable
for each key, val in array:
    if val is not in results:
        results[val] = new list()
    results[val].append(key)
return results

答案 3 :(得分:0)

也许这个?

$arr = array_map('unserialize', array_unique(array_map('serialize', $arr)));

问题: How to remove duplicated 2-dimension array in PHP?

if ($arr !== array_map('unserialize', array_unique(array_map('serialize', $arr))))
{
    // found duplicates
}

答案 4 :(得分:0)

您不必为每个元素再次遍历所有数组。仅测试具有数组中后续元素的元素:

$array = /* huge array */;
$size = count($array);
for($i = 0; $i < $size; $i++)
{
    for($j = $i + 1; $j < $size; $j++) // only test with the elements after $i
    {
        if($array[$i] == $array[$j])
            return true; // found a duplicate
    }
    return false; // found no duplicate
}

这是我能想到的最有效的方式。根据您的需要调整它。

答案 5 :(得分:0)

如果你的某个数组是相当静态的(也就是你要多次比较同一个数组),你可以将它反转。

设置另一个数组,该数组按值键入并将索引返回到实数数组中。

$invert = array();
foreach ($cmptoarray as $ix => $ival) {
   $invert[$ival] = $ix;
}

然后您只需要if ( isset($invert[$compfrmarray[$i]) ) ....来检查号码。

注意:如果您多次与同一个数组进行比较,这是值得做的!

答案 6 :(得分:0)

只需使用将值映射到其索引的关联数组:

foreach($array1 as $index => $value) {
    $aa[$value] = $index;
}

foreach($array2 as $index => $value) {
    if(isset($aa[$value])) {
        echo 'Duplicate:  .  Index 1:  '.$aa[$value].'  Index 2:  '.$index.'.';
    }
}