Поиск подмножеств массива в PHP
У меня есть реляционная схема с атрибутами (A B C D). У меня тоже есть набор функциональных зависимостей.
теперь мне нужно определить закрытие для всех возможных подмножеств атрибутов R. Вот где я застрял. Мне нужно научиться находить подмножества (неповторяющиеся) в PHP.
мой массив хранится следующим образом.
$ATTRIBUTES = ('A', 'B', 'C', 'D').
поэтому мои подмножества должны быть
$SUBSET = ('A', 'B', 'C', 'D', 'AB', 'AC', AD', 'BC', 'BD', 'CD', 'ABC', 'ABD', 'BCD', 'ABCD')
код не должен быть чем-то большим, но по какой-то причине я не могу постараюсь не думать об этом.
3 ответов
вы желаете для набора силы $attributes
? Вот что подразумевает ваш вопрос.
пример можно найти здесь (цитата Для полноты)
<?php
/**
* Returns the power set of a one dimensional array, a 2-D array.
* [a,b,c] -> [ [a], [b], [c], [a, b], [a, c], [b, c], [a, b, c] ]
*/
function powerSet($in,$minLength = 1) {
$count = count($in);
$members = pow(2,$count);
$return = array();
for ($i = 0; $i < $members; $i++) {
$b = sprintf("%0".$count."b",$i);
$out = array();
for ($j = 0; $j < $count; $j++) {
if ($b{$j} == '1') $out[] = $in[$j];
}
if (count($out) >= $minLength) {
$return[] = $out;
}
}
return $return;
}
используя php array_merge, мы можем иметь хорошую короткую функцию powerSet
function powerSet($array) {
// add the empty set
$results = array(array());
foreach ($array as $element) {
foreach ($results as $combination) {
$results[] = array_merge(array($element), $combination);
}
}
return $results;
}
вот обратное решение.
учитывая функцию, которая возвращает все подмножества L-длины входного набора, найдите все подмножества L-длины от L = 2 до длины входного набора данных
<?php
function subsets($S,$L) {
$a = $b = 0;
$subset = [];
$result = [];
while ($a < count($S)) {
$current = $S[$a++];
$subset[] = $current;
if (count($subset) == $L) {
$result[] = json_encode($subset);
array_pop($subset);
}
if ($a == count($S)) {
$a = ++$b;
$subset = [];
}
}
return $result;
}
$S = [ 'A', 'B', 'C', 'D'];
$L = 2;
// L = 1 -> no need to do anything
print_r($S);
for ($i = 2; $i <= count($S); $i++)
print_r(subsets($S,$i));