我已经产生了一个数字的素数因子 - 这应该是困难的部分!但是,为了创建相同数量的除数列表,需要在每种可能的方式中组合素因子。我正在努力用php做的事情。
例如我有一个数组:
2
2
2
3
3
41
53
...数字156456;将它们全部加在一起,然后你回到数字。我需要做的是将所有二重奏相乘,例如2x2,2x3,2x53等然后将所有三元组组合在一起,依此类推,直到我最终将7个6块块组合在一起。
正如你所看到的,这将给出一个非常大的数组,所有除数分别为4,6,8,9,12等,并且有许多重复。我似乎无法从上面的数组中得到我想要的除数数组。这是一个将数组中每个可能的元素组合相乘的情况,是否有一个php函数,到目前为止我的搜索没有结果?
答案 0 :(得分:1)
阅读本页后:http://mathcentral.uregina.ca/QQ/database/QQ.02.06/joe1.html,我尝试构建可能有用的内容,它可能不是最有效的解决方案,并且在32位系统上也仅限于count($primes) <= 32
。如果您需要更多内容,请随时使用Bitset:
$primes = Array(2, 2, 2, 3, 3, 41, 53);
$num_primes = count($primes); // 7, if this is over 32, it won't work on 32bit systems
$divisors = Array();
// number of possible combinations
$limit = pow(2, $num_primes) - 1; // 127
// count a number up and use the binary
// representation to say which index is
// part of the current divisor
for($number = 0; $number <= $limit; $number++) {
$divisor = 1;
// only multiply activated bits in $number to the divisor
for($i = 0; $i < $num_primes; $i++) {
$divisor *= ($number >> $i) & 1 ? $primes[$i] : 1;
}
$divisors[] = $divisor;
}
echo implode(", ", array_unique($divisors));
这导致以下除数:
1, 2, 4, 8, 3, 6, 12, 24, 9, 18, 36, 72, 41, 82, 164, 328, 123, 246, 492,
984, 369, 738, 1476, 2952, 53, 106, 212, 424, 159, 318, 636, 1272, 477,
954, 1908, 3816, 2173, 4346, 8692, 17384, 6519, 13038, 26076, 52152, 19557,
39114, 78228, 156456
要找到所有除数,您需要在每个可能的组合中将每个素数因子相乘。为此,我计算了可能的组合数($limit
)。如果您现在计算一个达到此限制的数字,则二进制表示看起来像这样:
7 bit
<----->
0000000 0
0000001 1
0000010 2
0000011 3
0000100 4
0000101 5
0000110 6
0000111 7
0001000 8
0001001 9
...
1111110 126
1111111 127
$number
的当前二进制表示表示$primes
的哪些索引用于计算当前$divisor
。为了更好地显示这个,我们说$number = 5
,二进制是0000101
。 $divisor
的计算结果为2 * 1 * 2 * 1 * 1 * 1 * 1 = 4
。仅设置第一个和第三个位,因此只有数组中的第一个和第三个元素用于计算。
我希望这会让它更清晰一点。