【问题标题】:PHP array intersect for only one occurrence of valuePHP数组相交仅出现一次值
【发布时间】:2017-03-12 04:08:15
【问题描述】:


我正在尝试创建一个函数来查找两个值的 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;
}

【问题讨论】:

  • 可能你的 prm_fac() 函数不正确。

标签: php arrays function sorting comparison


【解决方案1】:

您可以使用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 来获取实际的产品数组 - 这适用于我尝试过的 egs。

$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.

【讨论】:

  • 是的,那将是边缘情况,需要解决这个问题,也许 array_intersect 在这里没有帮助
  • 更新后的答案应该适用于上面讨论的边缘情况
  • 我尝试了 8 和 10,但我得到了 64 作为 HCF。我将新函数粘贴到 OP 中。
  • 你用上面提到的 array_unique 更新了你的 prm_fac() 函数吗?
  • 当我添加“return array_unique($factors);”直接进入prm_function,我得到的结果是4,作为8和10的HCF。我会将整个代码放入OP中。
【解决方案2】:

您可以使用此自定义函数代替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 的每个元素,并为每个元素调用第二个参数中提供的函数。如果该函数返回一个真值,则相应的元素将被包含(并且仅在那时)由array_filter 返回的数组中。

内部返回值计算如下:

($i = array_search($v, $b)) 查找来自 $a 的值 ($v) 在 $b 中出现的索引。该索引分配给变量$i(即时)。然后将其值与false 进行比较,这告诉我们是否匹配。如果不是,则不计算表达式的其余部分,因为 &amp;&amp; 永远无法使总表达式再次为真。所以返回值为false,即排除$a中的这个值(因为它不会出现在$b中)。

在另一种情况下,$i 将不是false,而是一个整数索引,所以第一个比较是true。然后评估&amp;&amp; 的下一部分:

($b[$i] = -1)

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

注释和参考

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

【讨论】:

  • 添加了功能说明部分。
猜你喜欢
  • 2016-12-19
  • 1970-01-01
  • 1970-01-01
  • 2020-06-03
  • 1970-01-01
  • 1970-01-01
  • 2013-12-05
  • 2011-06-13
  • 1970-01-01
相关资源
最近更新 更多