如何使用PHP中每个子数组中的一个值生成所有可能的组合?
问题描述:
我有一个显然很容易的任务,但我卡住了。我尝试了重构和迭代器,但没有想法打击我。他们说,一张图片的胜过千言万语,所以我会告诉我的“图像”例如数组:如何使用PHP中每个子数组中的一个值生成所有可能的组合?
array (size=4)
0 =>
array (size=4)
0 => int 1
1 => int 2
2 => int 3
3 => int 4
1 =>
array (size=3)
0 => string 'a' (length=1)
1 => string 'b' (length=1)
2 => string 'c' (length=1)
2 =>
array (size=3)
0 => string 'X' (length=1)
1 => string 'Y' (length=1)
2 => string 'Z' (length=1)
3 =>
array (size=5)
0 => string '!' (length=1)
1 => string '"' (length=1)
2 => string '#' (length=1)
3 => string '$' (length=1)
4 => string '%' (length=1)
规则:
- 数组大小和子阵列尺寸是随机的,而且相当巨大。
- 只能使用任何子数组中的一个值。
- 结果应从最短的字符串到最长的字符串排序。
- 由于生成了大量数据,因此必须提高内存效率,结果应该离线存储/比较,如文件或MySQL数据库。但每次都是。
所需的字符串组合的一个例子:
1
2
3
4
a
b
c
X ...
1a
1b
1c
2a
2b ...
aX!
aX" ...
1aX!
1aX" .......
4cZ%
我尝试了几种迭代器等How to generate in PHP all combinations of items in multiple arrays。
答
在我的情况下,解决方案是这个递归函数,我切换了$combine
变量,首先从数组插入单个值,然后将联合设置为true,合并数据库中的所有值(除了包含当前迭代的值值):
function iterdb($arrays, $i = 0, $combine = false) {
if (! isset(array_keys($arrays)[ $i ])) {
return false;
}
if ($i == 0 && $combine === true) {
//Adding empty option to obtain all combos
for ($x = 0; $x < count($arrays); $x ++) {
$arrays[ $x ][] = preg_replace('`=[^\&]+`', '=', $arrays[ $x ][0]);
}
}
$this->iterdb($arrays, $i + 1, $combine);//Call iteration on each following array
$transactions = array();
sort($arrays[ $i ]);
$this->log('Iterating array ' . $i . ' using combine ' . ($combine ? 'True' : 'False'));
foreach ($arrays[ array_keys($arrays)[ $i ] ] as $v) {
if ($this->counter > 0) {
if ($combine === false) {
$transactions[] = "INSERT IGNORE INTO scout_queries (scout,query) VALUES ('" . $this->Class . "','$v')";
} else {
$tmp = $this->queries->find(array(
'scout = :scout and query NOT LIKE :query',
':scout' => $this->Class,
':query' => '%' . (array_values(explode('=', $v))[0]) . '%'
), array('order' => 'CHAR_LENGTH(query) DESC'));
foreach ($tmp as $t) {
$transactions[] = "INSERT IGNORE INTO scout_queries (scout,query) VALUES ('" . $this->Class . "','" . $t->query . "&$v')";
$transactions = $this->saveTransactions($transactions);
}
}
}
$transactions = $this->saveTransactions($transactions, true);
}
if ($i == 0 && $combine === false) {
return $this->iterdb($arrays, 0, true);
}
}
因此,每行的长度介于1和数组中元素的数量?你想要所有可能的组合,还是只有几个,比如100? –
所有组合,数组大小都是随机的,在一个元素中最多可以有15000行,在一个数组中最多可以有50个元素。 – Ionut
这里似乎没有关于这个问题的简洁陈述。你能在第一段中总结一下吗? – halfer