Как получить все уникальные комбинации массива, включая пробелы (порядок элементов не имеет значения) - PullRequest
2 голосов
/ 24 июня 2019

У меня есть этот массив:

$array = array( 57, 53, 52 );

Я хочу получить все уникальные комбинации этих чисел (порядок элементов не имеет значения).

Я хочу результатв соответствии с:

// 57
// 57, 53
// 57, 53, 52

// 53

// 52
// 52, 57

Я использую эту функцию, но она возвращает каждую комбинацию значений, и, так как мне все равно, в каком порядке они представляют собой один и тот же результат, просто в другом порядке:

function my_function( $array ) {

    $combinations = array();
    $words = sizeof( $array );
    $combos = 1;

    for( $i = $words; $i > 0; $i-- ) {

        $combos *= $i;

    }

    while( sizeof( $combinations ) < $combos ) {

        shuffle($array);
        $combo = implode( " ", $array );

        if( !in_array( $combo, $combinations ) ) {

            $combinations[] = $combo;

        }

    }

    return $combinations;

}

print_r( my_function( $array ) );

Как мне этого добиться?

Ответы [ 3 ]

1 голос
/ 24 июня 2019

Так как порядок не имеет значения, похоже, что мы могли бы пройтись по порядку. Начните с первого номера и найдите все комбинации, затем перейдите ко второму в качестве нашего начального номера и так далее. И поскольку я люблю рекурсивные функции (рекурсия функций - это своя собственная награда), я бы так и поступил:

function unique_combinations( $array, $prefix = '' ) {
    $combinations = array();
    $count = count($array);
    // I use a for loop just to count the number of times to run. Since I'm using array_shift, the array will keep getting smaller
    for( $i = 0; $i < $count; $i++ ) {
        $number = array_shift($array);

        // Grab our current result (this number and any prefixes
        $this_result = trim( "$prefix $number" );
        $combinations[] = $this_result;

        // Now, if the array still has numbers in it, run the function on those numbers and combine results
        if ( count($array) > 0 ) {
            $combinations = array_merge($combinations, unique_combinations( $array, $this_result ) );
        }
    }

    return $combinations;
}

print_r( unique_combinations( [57,58,59] ) );
1 голос
/ 24 июня 2019

Подобный и довольно короткий рекурсивный подход с единственной анонимной функцией, sort и ранним array_unique. Должно дать вам то, что вы хотите, для простоты значения отсортированы в порядке возрастания:

// all the logic
$getAllCombinations = function($array) {
    $result = [];
    sort($array);
    $getOrderedCombinations = function ($combination_base, &$result) use (&$getOrderedCombinations) {
        array_push($result,$combination_base);
        if(count($combination_base) > 1) {
            foreach($combination_base as $key => $val) {
                $newcombo = $combination_base;
                unset($newcombo[$key]);
                $getOrderedCombinations($newcombo,$result);
            }
        }
    };
    $getOrderedCombinations($array,$result);
    return array_unique($result,SORT_REGULAR);
};


// execution
$array = array( 57, 53, 52  );
var_dump($getAllCombinations($array));
1 голос
/ 24 июня 2019
<?php

function my_function($array){
    $combs = [[]]; // adding empty set for better code clarity
    sort($array); // sort the array to avoid verbose code to handle duplicate combinations
    $set = [];

    foreach($array as $index => $element){
        $temp = [];
        foreach($combs as $curr_comb){
            $new_comb = $curr_comb;
            $new_comb[] = $element;
            $hashed_comb = implode(",",$new_comb);
            if(!isset($set[$hashed_comb])){
                $temp[] = $new_comb;
                $set[$hashed_comb] = true;
            }
        }

        $combs = array_merge($combs,$temp);
    }

    return array_slice($combs,1); // removing the empty set initially added
}

print_r(my_function([57,53,52]));
print_r(my_function([3,3,3]));

Демонстрация: https://3v4l.org/f3IHs

  • Мы добавляем пустую комбинацию [], чтобы код выглядел просто.
  • Мы генерируем комбинации, добавляя текущий элемент к предыдущему сгенерированному набору комбинаций.Например, сначала это [], которое позже становится [],[57], которое, в свою очередь, позже (в следующей итерации первого цикла foreach) становится [],[57],[53],[57,53] и т. Д.
  • Мы делаем implode() и вставляем вset запомнить комбинацию, чтобы избежать дублирования.
...