16

I am looking for an algorithm that will take numbers or words and find all possible variations of them together and also let me define how many values to look for together.

Example lets say the string or array is:

cat 
dog 
fish 

then the results for a value of 2 could be:

cat dog 
cat fish 
dog cat 
dog fish 
fish cat 
fish dog 

SO the results from the set of 3 items are 6 possible variations of it at 2 results matching
with 3 results matching it would be:

cat dog fish 
cat fish dog 
dog cat fish 
dog fish cat 
fish cat dog 
fish dog cat 

...probably more options even

I have found a link on Stackoverflow to this example that does this but it is in javascript, I am wondering if anyone knows how to do this in PHP maybe there is something already built?

(削除) http://www.merriampark.com/comb.htm (削除ここまで) (dead link)

mickmackusa
49.2k13 gold badges98 silver badges165 bronze badges
asked Aug 10, 2009 at 17:23
1
  • javascript link is dead Commented Jun 24, 2014 at 9:28

2 Answers 2

24

Take a look at http://pear.php.net/package/Math_Combinatorics

<?php
require_once 'Math/Combinatorics.php';
$words = array('cat', 'dog', 'fish');
$combinatorics = new Math_Combinatorics;
foreach($combinatorics->permutations($words, 2) as $p) {
 echo join(' ', $p), "\n"; 
}

prints

cat dog
dog cat
cat fish
fish cat
dog fish
fish dog
answered Aug 10, 2009 at 17:25
Sign up to request clarification or add additional context in comments.

4 Comments

Very nice PEAR package, I'll use it in the future.
That is awsome thanks for the info, do you have any idea what the difference between these 2 is $combinations and $permutations in the example script?
In permutations the order of the elements counts, in combinations the order is irrelevant. E.g. (cat,dog) and (dog,cat) both are included in the result of permutations() while the result of combinations() will only include one of them, the second is considered equal.
btw, you can copy Math_Combinatronics from here it works fine on it's own
15

If your looking for how something like this works, this is how i acheived it with no php libraries using binary.

function search_get_combos($query){
$list = explode(" ", $query);
$bits = count($list); //bits of binary number equal to number of words in query;
//Convert decimal number to binary with set number of bits, and split into array
$dec = 1;
$binary = str_split(str_pad(decbin($dec), $bits, '0', STR_PAD_LEFT));
while($dec < pow(2, $bits)) {
 //Each 'word' is linked to a bit of the binary number.
 //Whenever the bit is '1' its added to the current term.
 $curterm = "";
 $i = 0;
 while($i < ($bits)){
 if($binary[$i] == 1) {
 $curterm .= $list[$i]." ";
 }
 $i++;
 }
 $terms[] = $curterm;
 //Count up by 1
 $dec++;
 $binary = str_split(str_pad(decbin($dec), $bits, '0', STR_PAD_LEFT));
}
return $terms;
}

Note that this will return only unique combinations though, but can easily be extended to get every possible order of combinations so in your example this outputs:

Array
(
 [0] => fish 
 [1] => dog 
 [2] => dog fish 
 [3] => cat 
 [4] => cat fish 
 [5] => cat dog 
 [6] => cat dog fish 
)

Edit (More clarification)

Basic theory

So firstly, binary numbers as you probably know are a string of 1's and 0's. The length of the number is the number of 'bits' it has, eg. the number 011001 has 6 bits (The numbers 25 in case you interested). Then if each bit of the number corresponds to one of the terms, each time it counts up, if the bit is 1, the term is included in the output, whereas if it's 0, it is ignored. So thats the basic theory of what's happening.

Delving into the code

PHP has no way of counting in binary, but you can convert decimals to binary. So this function actually counts up in decimal, and converts that to binary. But because the number of bits is important, as each term needs its own bit, you need to add leading 0's, so thats what this bit does: str_pad(decbin($dec), $bits, '0', STR_PAD_LEFT)

Now this function uses a while loop, but as the number of times it needs to loop changes depending on how many terms there are, a bit of maths needs to be done. If you have ever worked with binary, you will know that the maximum number you can make is the 2^n (where n is the number of bits).

I think that should have covered all the confusing bits of the function, let me know if I've missed anything.

See what's happening

Use the following code to output the logic used, it may make a bit more sense seeing it this way!

function search_get_combos_demo($query){
 $list = explode(" ", $query);
 $bits = count($list);
 $dec = 1;
 while($dec < pow(2, $bits)) {
 $binary = str_split(str_pad(decbin($dec), $bits, '0', STR_PAD_LEFT));
 $curterm = "";
 $i = 0;
 while($i < ($bits)){
 if($binary[$i] == 1) {
 $curterm[] = $list[$i]." ";
 }
 $i++;
 }
 //-----DISPLAY PROCESS-----//
 echo "Iteration: $dec <table cellpadding=\"5\" border=\"1\"><tr>";
 foreach($binary as $b){
 echo "<td>$b</td>";
 }
 echo "</tr><tr>";
 foreach($list as $l){
 echo "<td>$l</td>";
 }
 echo "</tr></table>Output: ";
 foreach($curterm as $c){
 echo $c." ";
 }
 echo "<br><br>";
 //-----END DISPLAY PROCESS-----//
 $terms[] = $curterm;
 $dec++;
 }
 return $terms;
}
answered Jun 12, 2013 at 19:53

10 Comments

I have no idea how this works, can you add a bit more detail on the concept?
@TimoHuovinen I've updated my answer. Please let me know if it answers your questions, otherwise just let me know and I'll try to explain more
thank you for taking the time to clarify it, will delve into it later today.
@TimoHuovinen Try the function I've added at the end of my answer, it might make it a bit clearer to see whats going on, as it outputs a table for each iteration
Oh! Now I get it! The visual information helped! 1. You take 2 to the power of the number of words which is 8 for 3 words: "cat dog fish", if you count in binary until 8 it's 000,001,010,011,100,101,110,111. If you treat the first digit in the count as the rule to include "cat", the second for "dog" and the third for "fish" then counting in binary will include every possible combination! 001 = fish, 101 = cat fish, 111 = cat dog fish
|

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.