Reputation: 826
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
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
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