Я ищу алгоритм, который будет принимать числа или слова и находить все возможные варианты их вместе, а также дать мне определить, сколько ценностей нужно искать вместе.
Например, пусть строка или массив:
cat dog fish
то результаты для значения 2 могут быть:
cat dog cat fish dog cat dog fish fish cat fish dog
Таким образом, результаты из набора из 3-х элементов – это 6 возможных вариаций из двух результатов
с 3 результатами, соответствующими этому:
cat dog fish cat fish dog dog cat fish dog fish cat fish cat dog fish dog cat
… возможно больше вариантов даже
Я нашел ссылку на Stackoverflow на этот пример, который делает это, но он находится в javascript, мне интересно, знает ли кто-нибудь, как это сделать на PHP, возможно, что-то уже построено?
http://www.merriampark.com/comb.htm (мертвая ссылка)
Взгляните на 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"; }
печать
cat dog dog cat cat fish fish cat dog fish fish dog
Если вы ищете, как это работает, так это то, как я получил его без php-библиотек, использующих двоичный файл.
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; }
Обратите внимание, что это возвратит только уникальные комбинации, но может быть легко расширена, чтобы получить все возможные комбинации комбинаций, поэтому в вашем примере это выдает:
Array ( [0] => fish [1] => dog [2] => dog fish [3] => cat [4] => cat fish [5] => cat dog [6] => cat dog fish )
Итак, во-первых, двоичные числа, которые вы, вероятно, знаете, это строка из 1 и 0. Длина номера – это число «бит», которое у него есть, например. число 011001
имеет 6 бит (числа 25 в случае, если вы заинтересованы). Затем, если каждый бит номера соответствует одному из терминов, каждый раз, когда он подсчитывает, если бит равен 1, этот термин включается в выход, тогда как если он равен 0, он игнорируется. Итак, основная теория того, что происходит.
PHP не имеет возможности подсчета в двоичном формате, но вы можете преобразовать десятичные числа в двоичные. Таким образом, эта функция фактически подсчитывается в десятичной форме и преобразует ее в двоичную. Но поскольку число бит важно, так как каждому термину нужен свой собственный бит, вам нужно добавить ведущие 0, так что это то, что делает этот бит: str_pad(decbin($dec), $bits, '0', STR_PAD_LEFT)
Теперь эта функция использует цикл while, но поскольку количество раз, когда ему нужно циклически изменять изменения, в зависимости от того, сколько терминов имеется, нужно выполнить немного математики. Если вы когда-либо работали с двоичным кодом, вы будете знать, что максимальное число, которое вы можете сделать, это 2 ^ n (где n – количество бит).
Я думаю, что это должно было покрыть все запутанные части функции, сообщите мне, если я что-то пропустил.
Используйте следующий код для вывода используемой логики, возможно, это будет иметь больше смысла, видя его таким образом!
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; }
Вы можете попробовать этот открытый исходный код для этого. Он реализует итератор. Нажмите
Доступно в PHP, Java.
Вам нужно расширить его.