【问题标题】:How to get all the unique combinations of array including blanks (order of items not relevant)如何获取数组的所有唯一组合,包括空格(项目顺序不相关)
【发布时间】:2019-06-24 13:51:28
【问题描述】:

我有这个数组:

$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 ) );

我怎样才能做到这一点?

【问题讨论】:

  • order of the items not relevant => 所以我假设53, 5757, 53 是一样的。
  • 是的,我的场景是一样的
  • @Steveo 你应该更新你的例子!
  • 2^n 组合不少...
  • 递归函数的一个很好的例子

标签: php arrays unique


【解决方案1】:
<?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

  • 我们添加一个空组合[]before 使代码看起来简单。
  • 我们通过将当前元素添加到先前生成的组合集合来生成组合。比如,首先是[],后来变成[],[57],然后(在第一个foreach循环的下一次迭代中)变成[],[57],[53],[57,53]等等。
  • 我们使用implode() 并插入set 以记住组合以避免重复。

【讨论】:

    【解决方案2】:

    由于顺序无关紧要,看来我们可以按顺序完成。从第一个数字开始并找到所有组合,然后将第二个数字作为我们的起始数字,依此类推。因为我喜欢递归函数(函数递归是它自己的奖励),所以我会这样做:

    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] ) );
    

    【讨论】:

      【解决方案3】:

      一种类似且非常短的递归方法,具有单个匿名函数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));
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-04-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多