Display possible combinations of string
I am trying to take a string and display the possible combinations of it (in PHP), but while saying in order of each word. For example: "how are you" would return (an array)
How are you
How are
are you
how
you
are
The code I have now displays all combinations but I am wanting it to keep them in order and not flip words. Any one have any ideas or snippets they care to share? Thanks
Solution 1:
Set two iterators and print everything between them. So something like this:
<?
$str = "How are you";
$words = explode(" ",$str);
$num_words = count($words);
for ($i = 0; $i < $num_words; $i++) {
for ($j = $i; $j < $num_words; $j++) {
for ($k = $i; $k <= $j; $k++) {
print $words[$k] . " ";
}
print "\n";
}
}
?>
Output
How
How are
How are you
are
are you
you
Solution 2:
I know this is a very old post, but the other answer isn't very flexible, so I thought I would bring a new answer in.
Explanation
So you are looking for all combinations which would be:
(2n) - 1
Which in your specific example would be:
(23) - 1 = (8) - 1 = 7
So how do I get all combinations now? We loop through all our combinations, which we already have(Starting off with one combination, an "empty combination" ($results = [[]];
)), and for each combination we go through our next word from the array and combine each combination with each new word to a new combination.
Example
Array with the words/numbers (Empty array is '[]'):
[1, 2, 3]
//↓new combinations for the next iteration
│
iteration 0:
Combinations:
- [] │ -> []
│
iteration 1: ┌─────────────┤
│ │
Combinations: v v
- [] + 1 │ -> [1]
│
iteration 2: ┌─────────────┤
│ │
Combinations: v v
- [] + 2 │ -> [2]
- [1] + 2 │ -> [1,2]
│
iteration 3: ┌─────────────┤
│ │
Combinations: v v
- [] + 3 │ -> [3]
- [1] + 3 │ -> [1,3]
- [2] + 3 │ -> [2,3]
- [1,2] + 3 │ -> [1,2,3]
//^ All combinations here
So as you can see there is always: (2^n)-1
combinations in total. Also from this method there is an empty array left in the combination array, so before I return the array I just use array_filter()
to remove all empty arrays and array_values()
to reindex the entire array.
Code
<?php
$str = "how are you";
function getCombinations($array) {
//initalize array
$results = [[]];
//get all combinations
foreach ($array as $k => $element) {
foreach ($results as $combination)
$results[] = $combination + [$k => $element];
}
//return filtered array
return array_values(array_filter($results));
}
$arr = getCombinations(explode(" ", $str));
foreach($arr as $v)
echo implode(" ", $v) . "<br />";
?>
output:
how
are
how are
you
how you
are you
how are you
Solution 3:
Answer for question PHP array combination with out back order. There it was necessary to obtain all possible combinations of array elements and store the following.
<?php
$alphabet = array('a','b','c');
$result = array();
$arrResult = array();
// recursively create all possible combinations {
combine($alphabet, $result, $arrResult);
function combine($shiftedAlphabet, &$result, &$arrResult) {
global $alphabet;
$currentElementStr = '';
$currentElementArr = array();
for($i = 0; $i < count($shiftedAlphabet); ++$i) {
$newElement = $shiftedAlphabet[$i];
$currentElementStr .= $newElement;
$currentElementArr[] = $newElement;
if(!in_array($currentElementStr, $result)) { // if not duplicated => push it to result
// find right position {
$thisCount = count($currentElementArr);
$indexFrom = 0;
$indexToInsert = 0;
// find range of indexes with current count of elements {
foreach ($arrResult as $arrResultKey => $arrResultValue) {
$indexToInsert = $arrResultKey + 1;
if ($thisCount > count($arrResultValue)) {
$indexFrom = $indexToInsert;
}
if ($thisCount < count($arrResultValue)) {
--$indexToInsert;
break;
}
}
// find range of indexes with current count of elements }
// find true index inside true range {
$trueIndex = $indexToInsert;
$break = false;
for($j = $indexFrom; $j < $indexToInsert; ++$j) {
$trueIndex = $j + 1;
foreach($arrResult[$j] as $key => $value) {
if (array_search($value, $alphabet) > array_search($currentElementArr[$key], $alphabet)) {
$break = true;
break;
}
}
if($break) {
--$trueIndex;
break;
}
}
// find true index inside true range }
array_splice($result, $trueIndex, 0, $currentElementStr);
array_splice($arrResult, $trueIndex, 0, array($currentElementArr));
}
}
for($i = 0; $i < count($shiftedAlphabet) - 1; ++$i) {
$tmpShiftedAlphabet = $shiftedAlphabet; // for combining all possible subcombinations
array_splice($tmpShiftedAlphabet, $i, 1);
combine($tmpShiftedAlphabet, $result, $arrResult);
}
}
// recursively create all possible combinations }
var_dump($result);
?>
Example result here