PHP数组仅与一次出现的值相交

时间:2016-10-29 12:25:47

标签: php arrays function sorting comparison


我试图创建一个函数来查找两个值的HCF。我目前有一个函数可以找到每个值的所有素因子并将它们返回到数组中。要找到HCF,所有必须做的就是比较每个数组中的相似值,然后将它们相乘。 我的代码目前看起来像这样:

function hcf($x, $y) {
    $hcf = array_product(array_intersect(prm_fac($x), prm_fac($y)));
    if ($hcf != 0) 
        return $hcf;
    else
        return 1;

很难解释,所以我将展示一个问题的例子:如果我试图找到10和8的HCF,10的素数因子将是2,5; 8的素因子将是2,2,2。两个数组中的相似值将是2.

但是,当我使用array_intersect函数时,它会占用所有出现的2,而不仅仅是它相交的单个实例。因此,不是得到2,而是得到2,2,2。我该如何解决这个问题?

这是另一个例子:我需要找到4和16的HCF.4的主要因素是2,2; 16的素因子是2,2,2,2。我需要找到两个数组的值相同。如果我在两个数组上使用array_intersect,它将给我2,2,2,2而不是2,2。如何解决这个问题?


这是prm_fac函数:

function prm_fac($n) {
    $factors = array();
    while ($n % 2 == 0) {
        $factors[] = 2;
        $n /= 2;
    }
    for ($i = 3; $i <= sqrt($n); $i += 2) {
        while ($n % $i == 0) {
            $factors[] = $i;
            $n /= $i;
        }
    }
    if ($n != 1)
        $factors[] = $n;
    return $factors;
}

2 个答案:

答案 0 :(得分:1)

而不是array_intersect,您可以使用此自定义函数,这将考虑值可以重复,但只会在两个数组中重复多次时才会使用它们。

您的其余代码可以保留:

function common_values($a, $b) {
    return array_filter($a, function($v) use (&$b) {
        return ($i = array_search($v, $b)) !== false && ($b[$i] = -1);
    });
}

所以,请这样称呼:

function hcf($x, $y) {
    $hcf = array_product(common_values(prm_fac($x), prm_fac($y)));
    if ($hcf != 0) 
        return $hcf;
    else
        return 1;   
}

功能说明

array_filter($a, ...)遍历$a的每个元素,并为每个元素调用第二个参数中提供的函数。如果该函数返回一个truthy值,那么相应的元素将被包含在array_filter返回的数组中(并且仅在那里)。

该内部返回值计算如下:

($i = array_search($v, $b))找到$v中来自$a的值($b)的索引。该索引分配给变量$i(即时)。然后将其值与false进行比较,后者告诉我们是否存在匹配。如果不是,则不评估表达式的其余部分,因为&&永远不能使总表达式再次为真。因此返回值为false,即$a中的此值被排除(因为它不会出现在$b中)。

在另一种情况下,$i不是false而是整数索引,因此第一次比较是true。然后评估&&的下一部分:

($b[$i] = -1)

$b中的匹配值已消灭,以确保在任何下一次迭代中无法再次匹配。它被消除了负值,因为预期因子总是正数,非零值也是真实的,因此array_filter的返回值为真,即来自$a的这个值必须被包括在结果中。

注释和参考

请注意,HCF也称为GCD。另请参阅this solution以更直接的方式获取它,或使用GMP扩展中的gmp-gcd

答案 1 :(得分:0)

您可以使用array_unique()array_intersect()返回的结果数组中删除重复项。

我认为如果从prm_fac()数组中删除重复项会更好。类似的东西:

$hcf = array_product(array_intersect(array_unique(prm_fac($x)), array_unique(prm_fac($y))));

最佳做法是将它写在prm_fac函数本身 -

 function prm_fac($val) {
    .
    .
    .
    return array_unique($factors);
 }

我们可以利用foreach来获得实际的产品阵列 - 这适用于我尝试的例子。

$product = array();
$array1 = prm_fac($x); //return the unique $x values
$array2 = prm_fac($y); //return the unique $y values

foreach ($array1 as $val1) {
    foreach ($array2 as $val2) {
        // Form the product array if the iterated values are present in the other array
        if (in_array($val2, $array1) && in_array($val1, $array2)) {
            $product[] = $val1;
            $product[] = $val2;
        }
    }
}

最后,

$hcf = array_product($product); //should give the proper product of values.