Вот мой код, чтобы получить все возможности:
$seq[1] = 'd'; $seq[2] = 'f'; $seq[3] = 'w'; $seq[4] = 's'; for($i = 1; $i < 5; $i++) { $s['length_1'][] = $seq[$i]; $c1++; for($i2 = $i+1; $i2 < 5; $i2++) { $s['length_2'][] = $seq[$i].$seq[$i2]; $last = $seq[$i].$seq[$i2]; $c2++; for($i3 = $i2+1; $i3 < 5; $i3++) { $s['length_3'][] = $last.$seq[$i3]; $last = $last.$seq[$i3]; $c3++; for($i4 = $i3+1; $i4 < 5; $i4++) { $s['length_4'][] = $last.$seq[$i4]; $c4++; } } } } for($i = 0; $i < $c1; $i++) echo $s['length_1'][$i].'<br>'; for($i = 0; $i < $c2; $i++) echo $s['length_2'][$i].'<br>'; for($i = 0; $i < $c3; $i++) echo $s['length_3'][$i].'<br>'; for($i = 0; $i < $c4; $i++) echo $s['length_4'][$i].'<br>';
Но если я хочу добавить больше, то мне придется добавить еще один цикл. Итак, как я могу это сделать с рекурсией? Я пытаюсь, я стараюсь, но я действительно не могу этого сделать. Пожалуйста, помогите и отправьте пример как можно проще.
Спасибо.
Вот простой алгоритм. Итерация от 1 до 2 (массив) -1. На каждой итерации, если j-й бит в двоичном представлении счетчика циклов равен 1, включите j-й элемент в комбинацию.
Поскольку PHP должен уметь вычислять 2 count (array) как целое число, это может никогда не превышать PHP_INT_MAX
. На 64-битной установке PHP в вашем массиве не может быть более 62 элементов, так как 2 62 остается ниже PHP_INT_MAX
а 2 63 превышает его.
EDIT: Это вычисляет все возможные комбинации, а не перестановки (т. Е. 'Abc' = 'cba'). Он делает это, представляя исходный массив в двоичном выражении и «подсчитывая» от 0 до двоичного представления полного массива, эффективно создавая список всех возможных уникальных комбинаций.
$a = array('a', 'b', 'c', 'd'); $len = count($a); $list = array(); for($i = 1; $i < (1 << $len); $i++) { $c = ''; for($j = 0; $j < $len; $j++) if($i & (1 << $j)) $c .= $a[$j]; $list[] = $c; } print_r($list);
Один алгоритм здесь,
function getCombinations($base,$n){ $baselen = count($base); if($baselen == 0){ return; } if($n == 1){ $return = array(); foreach($base as $b){ $return[] = array($b); } return $return; }else{ //get one level lower combinations $oneLevelLower = getCombinations($base,$n-1); //for every one level lower combinations add one element to them that the last element of a combination is preceeded by the element which follows it in base array if there is none, does not add $newCombs = array(); foreach($oneLevelLower as $oll){ $lastEl = $oll[$n-2]; $found = false; foreach($base as $key => $b){ if($b == $lastEl){ $found = true; continue; //last element found } if($found == true){ //add to combinations with last element if($key < $baselen){ $tmp = $oll; $newCombination = array_slice($tmp,0); $newCombination[]=$b; $newCombs[] = array_slice($newCombination,0); } } } } } return $newCombs; }
Я знаю, что это не эффективно, но использование в небольших наборах не должно быть проблемой
Первый базовый параметр – это массив, содержащий элементы, которые следует учитывать при создании комбинаций.
для простого использования и вывода:
var_dump(getCombinations(array("a","b","c","d"),2));
и выход
array 0 => array 0 => string 'a' (length=1) 1 => string 'b' (length=1) 1 => array 0 => string 'a' (length=1) 1 => string 'c' (length=1) 2 => array 0 => string 'a' (length=1) 1 => string 'd' (length=1) 3 => array 0 => string 'b' (length=1) 1 => string 'c' (length=1) 4 => array 0 => string 'b' (length=1) 1 => string 'd' (length=1) 5 => array 0 => string 'c' (length=1) 1 => string 'd' (length=1)
Чтобы перечислить все подмножества массива, используя этот алгоритм комбинаций, просто выполните
$base =array("a","b","c","d"); for($i = 1; $i<=4 ;$i++){ $comb = getCombinations($base,$i); foreach($comb as $c){ echo implode(",",$c)."<br />"; } }
И выход
a b c d a,b a,c a,d b,c b,d c,d a,b,c a,b,d a,c,d b,c,d a,b,c,d
Вот:
<?php function combinations($text,$space) { // $text is a variable which will contain all the characters/words of which we want to make all the possible combinations // Let's make an array which will contain all the characters $characters=explode(",", $text); $x=count($characters); $comb = fact($x); // In this loop we will be creating all the possible combinations of the positions that are there in the array $characters for ($y=1; $y<= $comb; $y++) { $ken = $y-1; $f = 1; $a = array(); for($iaz=1; $iaz<=$x; $iaz++) { $a[$iaz] = $iaz; $f = $f*$iaz; } for($iaz=1; $iaz<=$x-1; $iaz++) { $f = $f/($x+1-$iaz); $selnum = $iaz+$ken/$f; $temp = $a[$selnum]; for($jin=$selnum; $jin>=$iaz+1; $jin--) { $a[$jin] = $a[$jin-1]; } $a[$iaz] = $temp; $ken = $ken%$f; } $t=1; // Let's start creating a word combination: we have all the necessary positions $newtext=""; // Here is the while loop that creates the word combination while ($t<=$x) { $newtext.=$characters[$a[$t]-1]."$space"; $t++; } $combinations[] = $newtext ; } return $combinations; } function fact($a){ if ($a==0) return 1; else return $fact = $a * fact($a-1); } $a = combinations("d,f,w,s",""); foreach ($a as $v) { echo "$v"."\n"; } ?>
Вывод:
dfws dfsw dwfs dwsf dsfw dswf fdws fdsw fwds fwsd fsdw fswd wdfs wdsf wfds wfsd wsdf wsfd sdfw sdwf sfdw sfwd swdf swfd
Также прочитайте это ;
Вы можете сделать это:
function combinations($arr) { $combinations = array_fill(0, count($arr)+1, array()); $combinations[0] = array(''); for ($i = 0, $n = count($arr); $i < $n; ++$i) { for ($l = $n-$i; $l > 0; --$l) { $combinations[$l][] = implode('', array_slice($arr, $i, $l)); } } return $combinations; }
Вот пример:
$arr = array('d', 'f', 'w', 's'); var_dump(combinations($arr));
Это создает следующий массив:
array( array(''), // length=0 array('d', 'f', 'w', 's'), // length=1 array('df', 'fw', 'ws'), // length=2 array('dfw', 'fws'), // length=3 array('dfws') // length=4 )
Краткое пояснение:
Для каждого i с 0 ≤ i < n , получим все подмассивы arr [ i , i + l] с каждой возможной длиной 0 < l ≤ n – i .
Это стандартный вопрос о перестановке, обратите внимание на «перестановки php», если вам нужны все варианты строки.
Вот моя функция для печати всех возможных комбинаций символов:
function printCombinations($var, $begin = 0, $preText = "") { for($i = $begin; $i < count($var); $i++) { echo $preText . $var[$i] . "\n"; if(($i+1) < count($var)) printCombinations($var, $i+1, $preText . $var[$i]); } } printCombinations(array('a','b','c','d','e'));