algoritmo que terá números ou palavras e encontrar todas as combinações possíveis
-
12-09-2019 - |
Pergunta
Eu estou procurando um algoritmo que vai levar números ou palavras e encontrar todas as variações possíveis de-los juntos e também deixe-me definir quantos valores para procurar juntos.
Exemplo vamos dizer que a corda ou matriz é:
cat
dog
fish
então os resultados para um valor de 2 poderia ser:
cat dog
cat fish
dog cat
dog fish
fish cat
fish dog
Assim, os resultados do conjunto de 3 itens são 6 possíveis variações do mesmo no 2 resultado de acordo
com 3 resultado de acordo seria:
cat dog fish
cat fish dog
dog cat fish
dog fish cat
fish cat dog
fish dog cat
... provavelmente mais opções mesmo
Eu encontrei um link em Stackoverflow a este exemplo que faz isso, mas é em javascript, eu estou querendo saber se alguém sabe como fazer isso em PHP talvez haja algo já construído?
http://www.merriampark.com/comb.htm (link morto)
Solução
Dê uma olhada http://pear.php.net/package/Math_Combinatorics
<?php
require_once 'Math/Combinatorics.php';
$words = array('cat', 'dog', 'fish');
$combinatorics = new Math_Combinatorics;
foreach($combinatorics->permutations($words, 2) as $p) {
echo join(' ', $p), "\n";
}
impressões
cat dog
dog cat
cat fish
fish cat
dog fish
fish dog
Outras dicas
Se o seu olhar para como algo como isso funciona, isto é como eu conseguido isso sem bibliotecas PHP usando binário.
function search_get_combos($query){
$list = explode(" ", $query);
$bits = count($list); //bits of binary number equal to number of words in query;
//Convert decimal number to binary with set number of bits, and split into array
$dec = 1;
$binary = str_split(str_pad(decbin($dec), $bits, '0', STR_PAD_LEFT));
while($dec < pow(2, $bits)) {
//Each 'word' is linked to a bit of the binary number.
//Whenever the bit is '1' its added to the current term.
$curterm = "";
$i = 0;
while($i < ($bits)){
if($binary[$i] == 1) {
$curterm .= $list[$i]." ";
}
$i++;
}
$terms[] = $curterm;
//Count up by 1
$dec++;
$binary = str_split(str_pad(decbin($dec), $bits, '0', STR_PAD_LEFT));
}
return $terms;
}
Note que isso irá retornar apenas combinações únicas, porém, mas pode ser facilmente estendido para obter toda ordem possível de combinações para que no seu exemplo deste saídas:
Array
(
[0] => fish
[1] => dog
[2] => dog fish
[3] => cat
[4] => cat fish
[5] => cat dog
[6] => cat dog fish
)
Editar (mais esclarecimentos)
Teoria básica
Assim, em primeiro lugar, números binários como você provavelmente sabe que são uma série de 1s e 0s. O comprimento do número é o número de 'bits' que tem, por exemplo. o número 011001
tem 6 bits (os números 25 no caso de você interessou). Então, se cada bit dos corresponde numéricos para um dos termos, cada vez que ele conta-se, se o bit é 1, o termo é incluído na saída, ao passo que se for 0, ele será ignorado. Então isso é a teoria básica do que está acontecendo.
investigando o código
PHP não tem nenhuma maneira de contar em binário, mas você pode converter números decimais para binário. Então esta função realmente conta em decimal, e convertidos que a binário. Mas porque o número de bits é importante, pois cada termo precisa de sua própria bit, você precisa adicionar líder 0 do, então isso é o que este bit faz: str_pad(decbin($dec), $bits, '0', STR_PAD_LEFT)
Agora, esta função usa um loop while, mas como o número de vezes que ele precisa de mudanças de loop dependendo de quantos termos existem, um pouco de necessidades de matemática a ser feito. Se você já trabalhou com o binário, você vai saber que o número máximo que você pode fazer é a 2 ^ n (onde n é o número de bits).
Eu acho que deveria ter coberto todos os bits confusa de função, deixe-me saber se eu perdi nada.
Veja o que está acontecendo
Use o seguinte código para a saída a lógica utilizada, pode fazer sentido um pouco mais vê-lo desta maneira!
function search_get_combos_demo($query){
$list = explode(" ", $query);
$bits = count($list);
$dec = 1;
while($dec < pow(2, $bits)) {
$binary = str_split(str_pad(decbin($dec), $bits, '0', STR_PAD_LEFT));
$curterm = "";
$i = 0;
while($i < ($bits)){
if($binary[$i] == 1) {
$curterm[] = $list[$i]." ";
}
$i++;
}
//-----DISPLAY PROCESS-----//
echo "Iteration: $dec <table cellpadding=\"5\" border=\"1\"><tr>";
foreach($binary as $b){
echo "<td>$b</td>";
}
echo "</tr><tr>";
foreach($list as $l){
echo "<td>$l</td>";
}
echo "</tr></table>Output: ";
foreach($curterm as $c){
echo $c." ";
}
echo "<br><br>";
//-----END DISPLAY PROCESS-----//
$terms[] = $curterm;
$dec++;
}
return $terms;
}
Você pode tentar este código-fonte aberto para isso. Ele implementa o iterador. Clique
Disponível em PHP, Java.
Você precisa estender-lo.