Home > Back-end >  How to get all the combinations of an array in php without functions
How to get all the combinations of an array in php without functions

Time:09-11

hope all of you are doing ok. I'm having a problem with this, because I'm looking for a way to get all the combinations of an array of numbers, but I want to do it without any function, I don't think that's possible, all the answers I already saw on internet have some function or method to do that.

I try this, give this array:

$numbers=[1,2,3,4];

I built 4 for loops to take the position of the array, and create a number, but, it supposes to be 24 different combinations give that array, with my for loops I get 256 combination

for($i = 0; $i <= 3; $i  ){
for($j = 0; $j <= 3;$j  ){
        for($k = 0;$k <= 3;$k  ){
            for($l = 0; $l <= 3;$l  ){
                 echo "$numbers[$i]$numbers[$j]$numbers[$k]$numbers[$l] <br>";
             }
         }
     } 
} 
>echo "Combinations: $contador \n";

Could someone please help me! (I want to get the combination on a new array per value, to compare later with a random number)

CodePudding user response:

Getting all combinations works on the principle of next permutation. This basically means it follows the below steps:

  • The input needs to be sorted as the starting combination. This eases out the calculations and produces a uniform result. Below snippet does use sort() inbuilt function but you can roll out for your own sort function(which I leave it to you as an exercise).

  • For a next permutation, we need to find 2 digits where smaller digit occupies an MSB place over the larger digit.

  • Once found, we swap those 2 digits and reverse the array from MSB 1 position. This reverse operation is to get next smallest lexicographic combination. If not performed, you will miss out on some needed in-between combinations.

  • The logic stops when the digits get sorted in non-increasing manner yielding the last combination possible.

Snippet:

<?php

function getCombinations($numbers){
  sort($numbers); // create your own custom function for sort.
  $result = [ $numbers ];
  do{
    $x = $y = -1;
    
    for($i = count($numbers) - 1; $i >= 0; --$i){
      for($j = $i - 1; $j >= 0; --$j){
        if($numbers[ $j ] < $numbers[ $i ] && ($y === -1 || $y < $j)){
          $x = $i;
          $y = $j;
        }
      }
    }
    
    if($x !== -1){
      swap($numbers, $x, $y);
      reverse($numbers, $y   1, count($numbers) - 1);
      $result[] = $numbers;
    }
  }while($x != -1);
  
  return $result;
}

function reverse(&$numbers, $left, $right){
  while($left < $right){
    swap($numbers, $left  , $right--);
  }
}

function swap(&$numbers, $x, $y){
  $temp = $numbers[ $x ];
  $numbers[ $x ] = $numbers[ $y ];
  $numbers[ $y ] = $temp;
}


print_r(getCombinations([1,2,3,4]));

Online Demo

CodePudding user response:

24 is the number of unique combinations - like this

for($i = 0; $i <= 3; $i  ){
for($j = 1; $j <= 3;$j  ){
        for($k = 2;$k <= 3;$k  ){
            for($l = 3; $l <= 3;$l  ){
                 echo "$numbers[$i]$numbers[$j]$numbers[$k]$numbers[$l] <br>";
             }
         }
     }
}

each digit can only appear once in each string

  • Related