Генерация всех возможных вариантов написания

Добрый день.

Возникла проблема в генерации всех возможных комбинаций заданных слов.
Допустим есть слова "слово1 слово2 слово3" разделенные пробелом, необходимо получить вот такой результат

слово1 слово2 слово3
слово1 слово3 слово2
слово2 слово1 слово3
слово2 слово3 слово1
слово3 слово1 слово2
слово3 слово2 слово1


мой пример выдает на каждое выполнение новую вариацию:
$text = 'слово1 слово2 слово3';
$array = explode( ' ', $text );
shuffle( $array );
$c = count( $array );
for( $q = 0; $q < $c; $q++ )
{
    echo $array[$q] . ' ';
}


не лепить же цикл в цикле...

P.S. в голову приходят идеи использовать бесконечный цикл + цикл для генерации, результат записывать в массив и делать каждый раз сверки. Как только массив достиг заданной длины (для трех слов это 6) выходим из циклов - но это какое-то извращение((
  • Вопрос задан
  • 4037 просмотров
Решения вопроса 2
Rsa97
@Rsa97
Для правильного вопроса надо знать половину ответа
Стандартная комбинаторная задача на перестановки, решается как рекурсивными, так и нерекурсивными алгоритмами, посмотреть можно, например, здесь
Вот реализация одного из алгоритмов на php:
$arr = array('word1', 'word2', 'word3');

$n = count($arr);
for ($i = 1; $i <= $n; $i++) {
    $pos[$i] = $i-1;
    $c[$i] = 1;
    $pr[$i] = 1;
}
$c[$n] = 0;

foreach($pos as $p)
    echo $arr[$p],' ';
echo "<br>";

$i = 1;
while ($i < $n) {
    $i = 1;
    $x = 0;
    while ($c[$i] == $n-$i+1) {
        $pr[$i] = 1-$pr[$i];
        $c[$i] = 1;
        $x += $pr[$i];
        $i++;
    }
    if ($i < $n) {
        $k = $pr[$i] ? $c[$i]+$x : $n-$i+1-$c[$i]+$x;
        $t = $pos[$k];
        $pos[$k] = $pos[$k+1];
        $pos[$k+1] = $t;
        foreach($pos as $p)
            echo $arr[$p],' ';
        echo "<br>";
        $c[$i]++;
    }
}

Результат:
word1 word2 word3
word2 word1 word3
word2 word3 word1
word3 word2 word1
word3 word1 word2
word1 word3 word2
Ответ написан
Комментировать
egor_nullptr
@egor_nullptr
function combinations($words)
{
    if (count($words) == 1) {
        return [$words];
    };

    $combinations = [];
    $i = 0;

    do {
        $first_word = array_shift($words);
        foreach (combinations($words) as $cmb) {
            $combinations[] = array_merge([$first_word], $cmb);
        };
        array_push($words, $first_word);
    } while (++$i < count($words));

    return $combinations;
};

$combinations = combinations(explode(' ', 'word1 word2 word3 word4'));

print_r($combinations);
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы