J'ai besoin d'un algorithme qui renvoie toutes les combinaisons possibles de tous les caractères dans une chaîne.
J'ai essayé:
$langd = strlen($input);
for($i = 0;$i < $langd; $i++){
$tempStrang = NULL;
$tempStrang .= substr($input, $i, 1);
for($j = $i+1, $k=0; $k < $langd; $k++, $j++){
if($j > $langd) $j = 0;
$tempStrang .= substr($input, $j, 1);
}
$myarray[] = $tempStrang;
}
Mais cela ne renvoie que la même combinaison de montant que la longueur de la chaîne.
Dit le $input = "hey"
, le résultat serait: hey, hye, eyh, ehy, yhe, yeh
.
Vous pouvez utiliser une approche basée sur le back tracking pour générer systématiquement toutes les permutations:
// function to generate and print all N! permutations of $str. (N = strlen($str)).
function permute($str,$i,$n) {
if ($i == $n)
print "$str\n";
else {
for ($j = $i; $j < $n; $j++) {
swap($str,$i,$j);
permute($str, $i+1, $n);
swap($str,$i,$j); // backtrack.
}
}
}
// function to swap the char at pos $i and $j of $str.
function swap(&$str,$i,$j) {
$temp = $str[$i];
$str[$i] = $str[$j];
$str[$j] = $temp;
}
$str = "hey";
permute($str,0,strlen($str)); // call the function.
Production:
#php a.php
hey
hye
ehy
eyh
yeh
yhe
Ma variante (fonctionne également avec l'entrée de tableau ou de chaîne)
function permute($arg) {
$array = is_string($arg) ? str_split($arg) : $arg;
if(1 === count($array))
return $array;
$result = array();
foreach($array as $key => $item)
foreach(permute(array_diff_key($array, array($key => $item))) as $p)
$result[] = $item . $p;
return $result;
}
P.S.: Downvoter, veuillez expliquer votre position. Ce code utilise str_split
et array_diff_key
fonctions standard, mais cet extrait de code est le le plus petit, il implémente pur récursivité de la queue avec un seul paramètre d'entrée et il est isomorphe au type de données d'entrée.
Peut-être qu'il perdra un peu les repères lors de la comparaison avec d'autres implémentations (mais les performances sont en fait presque les mêmes que dans la réponse de @ codaddict pour plusieurs chaînes de caractères), mais pourquoi nous ne pouvons pas simplement le considérer comme l'une des différentes alternatives qui a son ses propres avantages?
Je mettrais tous les caractères dans un tableau et j'écrirais une fonction récursive qui "rayerait" tous les caractères restants. Si le tableau est vide, vers un tableau de référence passé.
<?php
$input = "hey";
function string_getpermutations($prefix, $characters, &$permutations)
{
if (count($characters) == 1)
$permutations[] = $prefix . array_pop($characters);
else
{
for ($i = 0; $i < count($characters); $i++)
{
$tmp = $characters;
unset($tmp[$i]);
string_getpermutations($prefix . $characters[$i], array_values($tmp), $permutations);
}
}
}
$characters = array();
for ($i = 0; $i < strlen($input); $i++)
$characters[] = $input[$i];
$permutations = array();
print_r($characters);
string_getpermutations("", $characters, $permutations);
print_r($permutations);
Imprime:
Array
(
[0] => h
[1] => e
[2] => y
)
Array
(
[0] => hey
[1] => hye
[2] => ehy
[3] => eyh
[4] => yhe
[5] => yeh
)
Ah oui, les combinaisons = l'ordre n'ont pas d'importance. permutations = l'ordre importe.
Alors hé, hye yeh sont tous la même combinaison, mais 3 permutations distinctes comme mentionné. Attention, l'échelle des articles augmente très rapidement. Cela s'appelle factoriel et s'écrit comme 6! = 6 * 5 * 4 * 3 * 2 * 1 = 720 éléments (pour une chaîne de 6 caractères). Une chaîne de 10 caractères sera 10! = 3628800 permutations déjà, ce qui est un très grand tableau. Dans cet exemple, c'est 3! = 3 * 2 * 1 = 6.
Mon approche utilise la récursivité et aucune boucle, veuillez vérifier et donner votre avis:
function permute($str,$index=0,$count=0)
{
if($count == strlen($str)-$index)
return;
$str = rotate($str,$index);
if($index==strlen($str)-2)//reached to the end, print it
{
echo $str."<br> ";//or keep it in an array
}
permute($str,$index+1);//rotate its children
permute($str,$index,$count+1);//rotate itself
}
function rotate($str,$index)
{
$tmp = $str[$index];
$i=$index;
for($i=$index+1;$i<strlen($str);$i++)
{
$str[$i-1] = $str[$i];
}
$str[$i-1] = $tmp;
return $str;
}
permute("hey");