Forum Moderators: coopster

Message Too Old, No Replies

Combining variables in all combinations

         

erikcw

10:59 pm on Apr 20, 2005 (gmt 0)

10+ Year Member



Hi all,

I am creating an app that will take a 3 lists oy words or phrases (entered in a textarea form element) and produce all combinations of th lists.

For example, if you enter the words
"buy" and "sell" in the first box,

"blue" and "red" in the second box and

"widget" and "widgets in the third box

script would generate all combinations of these words like "buy widget" "buy widgets" "buy red widget" "sell red widget" "buy blue widget" "sell blue widget" "buy red widgets" "sell red widgets" "buy blue widgets" "sell blue widgets"

I think I will turn each list into an array (explode()), and then process, and then take the completed list an implode() back to a variable. I'm just not sure how to process the combinations.

Any ideas?

Thanks!

ironik

1:22 am on Apr 21, 2005 (gmt 0)

10+ Year Member



You are on the right track with exploding a string into an array.


$_POST['words1'] = "buy sell";
$_POST['words2'] = "blue red";
$_POST['words3'] = "widget widgets";

$words1 = array();
$words2 = array();
$words3 = array();

$words1 = explode(" ", $_POST['words1']);
$words2 = explode(" ", $_POST['words2']);
$words3 = explode(" ", $_POST['words3']);

$combinations = array();
foreach ($words1 as $word1)
{
foreach ($words2 as $word2)
{
foreach ($words3 as $word3)
{
$combinations[] = $word1 . ' ' . $word3;
$combinations[] = $word1 . ' ' . $word2 . ' ' . $word3;
}
}
}
// Remove duplicates
$combinations = array_unique($combinations);

// Test it out
print_r($combinations);

This should output a combinations array as you wanted. It's definitely not the only way to do it, but it works.

erikcw

11:20 pm on Apr 21, 2005 (gmt 0)

10+ Year Member



Thanks ironic! That worked like a charm!

No I have developed a followup question. How would a I do the same thing (create all possible combinations/orders), but with using a sentance as the source of objects (words) to re-order? The problem is that every sentance contians a differenf number of words. So I can't have a set of 3 loops to solve the problem, because what if there are 4 words or 10 words...

Here is what I've figured out so far...


$sentance = trim($sentance);
$sentance = explode(" ", $sentance);
foreach ($sentance as $v) {
// for count($sentance)
//
}

I am thinking it may have something to do with calculating the factorial of the number of words in the sentance...

Any ideas?

Thanks so much!

ironik

2:38 am on Apr 22, 2005 (gmt 0)

10+ Year Member



Ouch, that is much more difficult. You're basically wanting to create a power set of all the words and then re-factor them into an array of string combinations I think...

This should do the job:


$sentence = 'this, is a test sentence';

$words = array_unique(preg_split("/[\s,]+/", trim($sentence)));

$powerset = array(array( ));
foreach ($words as $word)
{
foreach ($powerset as $combo)
{
array_push($powerset, array_merge(array($word), $combo));
}
}

// Iterate and create new array of string combinations
$stringCombos = array();
foreach ($powerset as $k=>$v)
{
if ($v!= '')
{
$stringCombos[] = implode(' ', $powerset[$k]);
}
}
unset($powerset);

print_r($stringCombos);

I had a function laying around somewhere taken from a book, but can't find it. I used preg_split(), but I think split() also accepts a regex pattern, I'm just not sure how it behaves as I rarely use it. I didn't use explode this time around so you can account for commas and any other types of space characters (tabs etc). I'll be interested to see if this works properly for you as I can't test it right now.

erikcw

3:28 am on Apr 22, 2005 (gmt 0)

10+ Year Member



Thanks for your response ironik!

I gave your code a try, and here is the output:


Array
(
[0] =>
[1] => this
[2] => is
[3] => is this
[4] => a
[5] => a this
[6] => a is
[7] => a is this
[8] => test
[9] => test this
[10] => test is
[11] => test is this
[12] => test a
[13] => test a this
[14] => test a is
[15] => test a is this
[16] => sentence
[17] => sentence this
[18] => sentence is
[19] => sentence is this
[20] => sentence a
[21] => sentence a this
[22] => sentence a is
[23] => sentence a is this
[24] => sentence test
[25] => sentence test this
[26] => sentence test is
[27] => sentence test is this
[28] => sentence test a
[29] => sentence test a this
[30] => sentence test a is
[31] => sentence test a is this
)

I think explode is acctually ok if it can get the job done. The string input will have already been stripped of punctuation and special characters like tabs...

The problem with the output above is that the needed result is a list of phrases that are the same length as the original. So if the input has 5 words, than the output array needs to have 4 words for each of the variations. (If I recall statistics correctly I think it is a permutaion (nPr) not a combination (nCr).

Thanks again so much for your help!

ironik

3:49 am on Apr 22, 2005 (gmt 0)

10+ Year Member



I also noticed that output is not quite what I was expecting and you'd need an extra combination 'shuffler' if you had wanted every possible combination (not just unique combinations of words).

Permutation is a different kettle of fish and I hate to admit it's a little beyond something I'd be able to write quickly.