我有 2 个这样的字符串
$s1="32.56.86.90.23";
$s2="11.25.32.90.10";
我需要比较$s1
和$s2
,看看是否有 2 个或更多数字是共同的。
我正在使用这种方式
$s1_ar=explode(".",$s1);
$s2_ar=explode(".",$s2);
$result=array_diff($s1_ar,$s2_ar);
$rt1=5-count($result);
if($result>=2){ echo "YES"; } else {echo "no"; }
由于我需要数百万个$s1
值和$s2
并且上面的代码似乎很慢,您知道更快地执行工作的替代方法吗?
我用以下代码测试了它,一百万次,在我 2 年前的笔记本电脑上不到 3 秒。
循环1M时间不需要时间,大部分时间用于显示。
关闭显示屏注释,1M 循环,0.816432 秒
将结果保存到文件中, ~13.564MB, 0.731708 秒
ob_start();
$t1 = microtime();
for($i=1; $i<=1000000; $i++) {
$s1="32.56.86.90.23";
$s2="10.25.30.90.10";
$s1_ar=explode(".",$s1);
$s2_ar=explode(".",$s2);
$result=array_diff($s1_ar,$s2_ar);
$rt1=5-count($result);
if($result>=2){ echo $i . " YES<br>"; } else {echo $i . " no<br>"; }
}
$out = ob_get_contents();
ob_end_clean();
var_dump($out);
echo '<p>'.(microtime() - $t1).'</p>';
试试这个。
$s1="32.56.86.90.23";
$s2="11.23.32.90.10";
$s1_ar=explode(".",$s1);
$s2_ar=explode(".",$s2);
//assuming $s1_ar and $s2_ar both has unique values if not please make them unique
$result_array = array();
$hasMatch = 0;
for($i = 0; $i < count($s1_ar) && $i < count($s2_ar); $i++){
if(!isset($result_array[$s1_ar[$i]])){
$result_array[$s1_ar[$i]] = 1;
}else{
$result_array[$s1_ar[$i]]++;
}
if(!isset($result_array[$s2_ar[$i]])){
$result_array[$s2_ar[$i]] = 1;
}else{
$result_array[$s2_ar[$i]]++;
}
}
foreach($result_array as $result){
if($result >=2) $hasMatch++;
}
if($hasMatch >= 2)
echo "YES";
else
echo "NO";
我认为它会解决你的目的。
查看: php array_intersect(( 效率
有人提到array_intersect_key可能更有效率。 但实际上,有数据和版本来比较结果会很好。
$s1 = "2.3.5.7.9.11.13.17";
$s2 = "2.3.4.5.6";
$s1 = array_flip(explode('.', $s1));
$s2 = array_flip(explode('.', $s2));
echo count(array_intersect_key($s1, $s2))>=2 ? 'yes' : 'no';
输出:
yes
到了一种方法来解决这个问题,复杂度为 2*n:我们循环一个列表并从它的元素(LIST c(创建一个关联数组,然后我们循环第二个列表并查找列表c是否包含这样的索引/键(c[element](。这应该是非常轻的权重:
$commons = 0;
$s1_fliped = array_flip($s1_ar)
foreach($s2_ar as $s2_el){
if ( isset($s1_fliped[$s2_el]) ){
$commons ++;
}
if($commons >=2) break;
});