我已经有一个找到2个数字的GCD的函数。
function getGCDBetween($a, $b)
{
while ($b != 0)
{
$m = $a % $b;
$a = $b;
$b = $m;
}
return $a;
}
但是现在,我想扩展这个功能来找到N点的GCD。有什么建议吗?
答案 0 :(得分:16)
有一种更优雅的方法:
// Recursive function to compute gcd (euclidian method)
function gcd ($a, $b) {
return $b ? gcd($b, $a % $b) : $a;
}
// Then reduce any list of integer
echo array_reduce(array(42, 56, 28), 'gcd'); // === 14
如果您想使用浮点数,请使用近似值:
function fgcd ($a, $b) {
return $b > .01 ? fgcd($b, fmod($a, $b)) : $a; // using fmod
}
echo array_reduce(array(2.468, 3.7, 6.1699), 'fgcd'); // ~= 1.232
您可以在PHP 5.3中使用闭包:
$gcd = function ($a, $b) use (&$gcd) { return $b ? $gcd($b, $a % $b) : $a; };
答案 1 :(得分:7)
不得不做一些挖掘,但是this is what I found。
三个数字的gcd可以计算为gcd(a,b,c)= gcd(gcd(a, b),c),或以某种不同的方式应用交换性和 关联。这可以扩展到任意数量的数字。
您可以使用以下内容:
function multiGCD($nums)
{
$gcd = getGCDBetween($nums[0], $nums[1]);
for ($i = 2; $i < count($nums); $i++) { $gcd = getGCDBetween($gcd, $nums[$i]); }
return $gcd;
}
答案 2 :(得分:2)
你可以尝试
function gcd($a, $b) {
if ($a == 0 || $b == 0)
return abs(max(abs($a), abs($b)));
$r = $a % $b;
return ($r != 0) ? gcd($b, $r) : abs($b);
}
function gcd_array($array, $a = 0) {
$b = array_pop($array);
return ($b === null) ? (int) $a : gcd_array($array, gcd($a, $b));
}
echo gcd_array(array(50, 100, 150, 200, 400, 800, 1000)); // output 50
答案 3 :(得分:2)
取数字1和2的GCD,然后取GCD和数字3,依此类推。
答案 4 :(得分:1)
我找到了一个解决方案,但看起来有点难看:
1)检查每个整数的每个除数
2)在每个数组中找到更大的整数
function getAllDivisorsOf($n)
{
$sqrt = sqrt($n);
$divisors = array (1, $n);
for ($i = 2; ($i < $sqrt); $i++)
{
if (($n % $i) == 0)
{
$divisors[] = $i;
$divisors[] = ($n / $i);
}
}
if (($i * $i) == $n)
{
$divisors[] = $i;
}
sort($divisors);
return $divisors;
}
function getGCDFromNumberSet(array $nArray)
{
$allDivisors = array ();
foreach ($nArray as $n)
{
$allDivisors[] = getAllDivisorsOf($n);
}
$allValues = array_unique(call_user_func_array('array_merge', $allDivisors));
array_unshift($allDivisors, $allValues);
$commons = call_user_func_array('array_intersect', $allDivisors);
sort($commons);
return end($commons);
}
echo getGCDFromNumberSet(array(50, 100, 150, 200, 400, 800, 1000)); // 50
有更好的主意吗?
答案 5 :(得分:0)
您可以将数字存储在数组和/或数据库中,然后从那里读取。然后在循环中,您可以对数组元素进行模块划分。
答案 6 :(得分:0)
您还可以使用gmp库:
<?php
$gcd = gmp_gcd( '12', '21' );
echo gmp_strval( $gcd );
?>
答案 7 :(得分:0)
我发现这是通过递归计算gcd的地方
function gcd(...$numbers) {
if (count($numbers) > 2) {
return array_reduce($numbers, 'gcd'); // use php's array reduce
}
$r = $numbers[0] % $numbers[1];
return $r === 0 ? abs($numbers[1]) : gcd($numbers[1], $r);
}