Rick
Rick

Reputation: 826

All three word combinations (in the same order) from a string

Let's say we have a string with words:
1 2 3 4 5

I want all combinations of three words, but the order can't change. The string can be anywhere from 4 words up to 7 words long. Not longer as there would be too many combinations. So the result for the example 1 2 3 4 5 would be an array with strings:
1 2 3
1 2 4
1 2 5
1 3 4
1 3 5
1 4 5
2 3 4
2 3 5
2 4 5
3 4 5

I've been thinking about this for a while. One idea was to turn it into an array, generate a binary code for the amount of words and if it is a 1 then it shows the word and otherwise it doesn't (so you get anything from 11100 to 00111). But that's probably not optimal.

Speed matters in this case, as it possible has to be done tens of thousands of times within a few minutes.

Upvotes: 1

Views: 822

Answers (2)

Vicky Gonsalves
Vicky Gonsalves

Reputation: 11717

you can do it as:

<?php
function everyCombination($array)
{
    $arrayCount = count($array);
    $resultArray = array();
    $veryFinal = array();
    $maxCombinations = pow($arrayCount, $arrayCount);
    $returnArray = array();
    $conversionArray = array();
    foreach ($array as $key => $value) {
        $conversionArray[base_convert($key, 10, $arrayCount)] = $value;
    }
    for ($i = 0; $i < $maxCombinations; $i++) {
        $combination = base_convert($i, 10, $arrayCount);
        $combination = str_pad($combination, $arrayCount, "0", STR_PAD_LEFT);
        $returnArray[] = strtr($combination, $conversionArray);
    }
    $finalArray = array();
    foreach ($returnArray as $sepArray) {
        array_push($finalArray, array_unique(str_split($sepArray)));
    }
    foreach ($finalArray as $result) {
        $temp = implode(",", $result);
        if (count($result) == 3) {
            array_push($resultArray, $temp);
        }
    }
    $tempFinal = array_unique($resultArray);
    foreach ($tempFinal as $final) {
        array_push($veryFinal, $final);
    }
    return $veryFinal;
}


$res1 = (everyCombination(array(1, 2, 3, 4)));
$res2 = (everyCombination(array('a','b','c','d')));
var_dump($res1);
var_dump($res2);

It Gives:

array (size=24)
  0 => string '1,2,3' (length=5)
  1 => string '1,2,4' (length=5)
  2 => string '1,3,2' (length=5)
  3 => string '1,3,4' (length=5)
  4 => string '1,4,2' (length=5)
  5 => string '1,4,3' (length=5)
  6 => string '2,1,3' (length=5)
  7 => string '2,1,4' (length=5)
  8 => string '2,3,1' (length=5)
  9 => string '2,3,4' (length=5)
  10 => string '2,4,1' (length=5)
  11 => string '2,4,3' (length=5)
  12 => string '3,1,2' (length=5)
  13 => string '3,1,4' (length=5)
  14 => string '3,2,1' (length=5)
  15 => string '3,2,4' (length=5)
  16 => string '3,4,1' (length=5)
  17 => string '3,4,2' (length=5)
  18 => string '4,1,2' (length=5)
  19 => string '4,1,3' (length=5)
  20 => string '4,2,1' (length=5)
  21 => string '4,2,3' (length=5)
  22 => string '4,3,1' (length=5)
  23 => string '4,3,2' (length=5)
array (size=24)
  0 => string 'a,b,c' (length=5)
  1 => string 'a,b,d' (length=5)
  2 => string 'a,c,b' (length=5)
  3 => string 'a,c,d' (length=5)
  4 => string 'a,d,b' (length=5)
  5 => string 'a,d,c' (length=5)
  6 => string 'b,a,c' (length=5)
  7 => string 'b,a,d' (length=5)
  8 => string 'b,c,a' (length=5)
  9 => string 'b,c,d' (length=5)
  10 => string 'b,d,a' (length=5)
  11 => string 'b,d,c' (length=5)
  12 => string 'c,a,b' (length=5)
  13 => string 'c,a,d' (length=5)
  14 => string 'c,b,a' (length=5)
  15 => string 'c,b,d' (length=5)
  16 => string 'c,d,a' (length=5)
  17 => string 'c,d,b' (length=5)
  18 => string 'd,a,b' (length=5)
  19 => string 'd,a,c' (length=5)
  20 => string 'd,b,a' (length=5)
  21 => string 'd,b,c' (length=5)
  22 => string 'd,c,a' (length=5)
  23 => string 'd,c,b' (length=5)

Upvotes: 0

Bhavik Shah
Bhavik Shah

Reputation: 2291

I have used Vicky's answer and did some modifications. I think this will work as you want

function everyCombination($array) {
    $tempcount = 3;                            //lenght of the combinations you want
    $arrayCount      = count($array);
    $maxCombinations = pow($arrayCount, $arrayCount);
    $returnArray     = array();
    $conversionArray = array();
    foreach ($array as $key => $value) {
        $conversionArray[base_convert($key, 10, $arrayCount)] = $value;
    }
    for ($i = 0; $i < $maxCombinations; $i++) {
        $flag = 1;
        $combination = base_convert($i, 10, $arrayCount);
        $combination = str_pad($combination, $tempcount, "0", STR_PAD_LEFT);
        $temp = strtr($combination, $conversionArray);
        for($j = 0; $j < $tempcount-1; $j++){

            if($temp[$j] >= $temp[$j+1] || $flag == 0)
                $flag = 0;
            else
                $flag = 1;
        }
        if($flag && strlen($temp) == $tempcount)
            $returnArray[] = $temp;
    }
    return $returnArray;
}

print_r(everyCombination(array(1,2,3,4)));

Upvotes: 1

Related Questions