Php 查找重复/冲突时的阵列循环性能

Php 查找重复/冲突时的阵列循环性能,php,arrays,performance,Php,Arrays,Performance,这段代码在一系列事件中循环,每个事件都有开始和结束时间。。。并简单地设置一个“匹配”键,表示它已匹配另一个事件(即要解决的冲突): 但是我想不出一种优雅的方式来处理这个问题,而不使代码更难阅读 一种可能是创建一个新的数组,其中包含“通过”检查的事件,但我怀疑在数组中添加/删除元素的内存管理远不止是简单的整数检查。可以使用两个数字循环,而不是使用foreach。然后,您的“内部循环”可以从当前的外部值+1开始,并且您不会处理任何双重组合 $cachedCount = count($array);

这段代码在一系列事件中循环,每个事件都有开始和结束时间。。。并简单地设置一个“匹配”键,表示它已匹配另一个事件(即要解决的冲突):

但是我想不出一种优雅的方式来处理这个问题,而不使代码更难阅读


一种可能是创建一个新的数组,其中包含“通过”检查的事件,但我怀疑在数组中添加/删除元素的内存管理远不止是简单的整数检查。

可以使用两个数字循环,而不是使用foreach。然后,您的“内部循环”可以从当前的
外部值+1开始,并且您不会处理任何双重组合

$cachedCount = count($array);
for ($outer = 0; $outer < $cachedCount; $outer++){
  for ($inner = $outer+1; $inner< $cachedCount; $inner++){
    // process entries. no duplicates here. Only the ones that are dupplicates, 
    // but shouldn't be.
  }
}
它将具有以下步骤:

outer = 0; inner = 1; //a-b
outer = 0; inner = 2; //a-c
outer = 0; inner = 3; //a-d

outer = 1; inner = 2; //b-c
outer = 1; inner = 3; //b-d

outer = 2; inner = 3; //c-d

因此,检查所有组合,但未处理重复(
a-c
c-a
)或小组合(
a-a
b-b
)。显然,对于2个元素,它将以比较
0-1
开始和结束。(与进行2by2迭代的4个比较相比,这是一个比较(
1-1
1-2
2-1
2-2

您可以使用索引来调整循环的大小:

<?php
$arr = array( '1', '2', '3', '4' );
for($a=0; $a<count($arr); $a++){
    for($b=0; $b<$a; $b++){
        echo "compare: ".$arr[$a]." ".$arr[$b].",\n";
    }
}

//Ouput
//compare: 2 1,
//compare: 3 1,
//compare: 3 2,
//compare: 4 1,
//compare: 4 2,
//compare: 4 3,

可能类似于:

foreach ($results as $p_id => $p_result) {
    foreach (array_slice($results, $p_id+1, NULL, true) as $c_id => $c_result) {
        if ($p_result['from'] < $c_result['to'] && $p_result['to'] > $c_result['from']) {
            $results[$p_id]['match'] = $c_id;
            break;
        }
    }

}
foreach($p_id=>p_结果){
foreach(数组_切片($results,$p_id+1,NULL,true)为$c_id=>$c_result){
如果($p_result['from']<$c_result['to']&&$p_result['to']>$c_result['from']){
$results[$p_id]['match']=$c_id;
打破
}
}
}

看起来不错……虽然不是特别科学,但那是0.6秒(也会检查其他时间)……现在只是想知道是否可以将数组_切片()替换为
的内部
,这样我们就不会在内存中创建一组新的数组了?感谢马克,虽然它基本上与@dognose的解决方案相同,但使用数组_切片()将此解决方案的速度减慢了一点…但是感谢您的建议,拥有第二双眼睛当然很好。注意到有一些更新…我认为您已经注意到了一些…需要更改的一件事是重复调用count(),可以缓存。@CraigFrancis,可以缓存是的。由于count函数在没有参数的情况下无法工作,因此它只是一个“口头”示例。;)刚刚测试,现在得到0.1秒。。。感谢您更新以显示cachedCount(我知道它不合理,但我讨厌在for语句中看到函数调用)。。。将进行更多测试,但我认为我们有一个赢家。@CraigFrancis忽略注释通知-它是正确的:P@CraigFrancis我喜欢你详细阐述所有答案的方式。这为所有在同一问题上结结巴巴的访问者增加了“质量”!谢谢@lemiant,不幸的是dognose赢了你几秒钟。。。但是谢谢你的帮助,我想今天下午我不应该被允许在键盘后面。。。此外,还有一些小的调整,但如果缓存count()函数调用,还可以节省几毫秒。
outer = 0; inner = 1; //a-b
outer = 0; inner = 2; //a-c
outer = 0; inner = 3; //a-d

outer = 1; inner = 2; //b-c
outer = 1; inner = 3; //b-d

outer = 2; inner = 3; //c-d
<?php
$arr = array( '1', '2', '3', '4' );
for($a=0; $a<count($arr); $a++){
    for($b=0; $b<$a; $b++){
        echo "compare: ".$arr[$a]." ".$arr[$b].",\n";
    }
}

//Ouput
//compare: 2 1,
//compare: 3 1,
//compare: 3 2,
//compare: 4 1,
//compare: 4 2,
//compare: 4 3,
foreach ($results as $p_id => $p_result) {
    foreach (array_slice($results, $p_id+1, NULL, true) as $c_id => $c_result) {
        if ($p_result['from'] < $c_result['to'] && $p_result['to'] > $c_result['from']) {
            $results[$p_id]['match'] = $c_id;
            break;
        }
    }

}