алгоритм, который будет брать числа или слова и находить все возможные комбинации

Я ищу алгоритм, который будет брать числа или слова и находить все их возможные варианты вместе, а также позволять мне определять, сколько значений искать вместе.

Пример позволяет сказать, что строка или массив:

cat  
dog  
fish  

тогда результаты для значения 2 могут быть:

cat dog  
cat fish  
dog cat  
dog fish  
fish cat  
fish dog   

Итак, результаты из набора из 3 элементов - это 6 возможных вариантов его при 2 совпадениях результатов
с 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 (мертвая ссылка)


person JasonDavis    schedule 10.08.2009    source источник
comment
ссылка javascript мертва   -  person Timo Huovinen    schedule 24.06.2014


Ответы (2)


Взгляните на 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
person VolkerK    schedule 10.08.2009
comment
Очень красивый пакет PEAR, буду использовать его в будущем. - person Alix Axel; 10.08.2009
comment
Большое спасибо за информацию. Вы хоть представляете, в чем разница между этими двумя комбинациями $ is $ и $ перестановками в примере скрипта? - person JasonDavis; 11.08.2009
comment
В перестановках учитывается порядок элементов, в комбинациях порядок не имеет значения. Например. (кошка, собака) и (собака, кошка) оба включаются в результат перестановок (), в то время как результат комбинаций () будет включать только один из них, второй считается равным. - person VolkerK; 11.08.2009
comment
кстати, вы можете скопировать Math_Combinatronics из здесь он отлично работает сам по себе - person Timo Huovinen; 24.06.2014

Если вы ищете, как что-то вроде этого работает, вот как я добился этого без библиотек 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 
)

Изменить (дополнительные пояснения)

Основная теория

Итак, во-первых, двоичные числа, как вы, наверное, знаете, представляют собой строку из единиц и нулей. Длина числа - это количество «битов», которое оно имеет, например. число 011001 имеет 6 бит (числа 25, если вам интересно). Затем, если каждый бит числа соответствует одному из членов, каждый раз, когда он подсчитывается, если бит равен 1, член включается в вывод, тогда как если он 0, он игнорируется. Это основная теория происходящего.

Углубляясь в код

PHP не имеет возможности считать в двоичном формате, но вы можете преобразовать десятичные числа в двоичные. Таким образом, эта функция фактически считает в десятичном виде и преобразует его в двоичный. Но поскольку количество битов важно, так как каждому члену нужен свой бит, вам нужно добавить ведущие нули, так вот что делает этот бит: 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;
}
person Adi Bradfield    schedule 12.06.2013
comment
Понятия не имею, как это работает, не могли бы вы подробнее рассказать о концепции? - person Timo Huovinen; 25.07.2013
comment
@TimoHuovinen Я обновил свой ответ. Пожалуйста, дайте мне знать, если он ответит на ваши вопросы, в противном случае просто дайте мне знать, и я постараюсь объяснить больше - person Adi Bradfield; 25.07.2013
comment
Спасибо, что нашли время прояснить это, я углублюсь в это сегодня позже. - person Timo Huovinen; 26.07.2013
comment
@TimoHuovinen Попробуйте функцию, которую я добавил в конце своего ответа, она может немного прояснить, что происходит, поскольку она выводит таблицу для каждой итерации - person Adi Bradfield; 29.07.2013
comment
Ой! Теперь я понимаю! Визуальная информация помогла! 1. Вы берете 2 в степень числа слов, которая равна 8 для 3 слов: кошка собака рыба, если вы считаете в двоичном формате до 8, это 000,001,010,011,100,101,110,111. Если вы считаете, что первая цифра в счетчике включает кошку, вторую - собаку, а третью - рыбу, то при подсчете в двоичном формате будут учитываться все возможные комбинации! 001 = рыба, 101 = рыба-кошка, 111 = рыба-кошка, собака - person Timo Huovinen; 30.07.2013
comment
@TimoHuovinen На месте! Отлично, не правда ли? - person Adi Bradfield; 30.07.2013
comment
Да! это определенно так. - person Timo Huovinen; 30.07.2013
comment
@TimoHuovinen Проблема в том, что я подумал об этом, но теперь мне нужно отказаться от этого, поскольку в моем коде он стал избыточным! Неважно, когда-нибудь я найду ему применение! - person Adi Bradfield; 30.07.2013
comment
StackOverflow в этом плане крутой, он позволяет хранить биты рабочего кода и делиться им со всеми, я часто получаю код, который не нужен ни в одном из моих активных проектов, но я могу вернуться к нему, настроить его и все снова начинает жить. - person Timo Huovinen; 30.07.2013
comment
@TimoHuovinen Да, ТАК замечательный ресурс! Помогал мне во многих ситуациях, я просто хочу, чтобы у меня было немного больше, чтобы отдать сообществу! : ') - person Adi Bradfield; 30.07.2013