6

Not sure how to explain. Let's use an example. Say I want to split the sentence

"Today is a great day."

into

today
today is
today is a
today is a great
today is a great day
is
is a
is a great
is a great day
a
a great
a great day
great
great day
day

The idea is to get all the sequential combination in a sentence.

I have been thinking what's the best way to do it in PHP. Any idea is welcome.

3
  • I'm sure there's a fancy recursive method of doing this. Commented May 7, 2010 at 7:59
  • How to treat duplicate words: "This is easy, is it?"? Are numbers considered words? What about punctuation? Commented May 7, 2010 at 8:01
  • Duplicate is easy. Put them into an array and get unique array. What I can't figure out is how to get all the combination into an array. Commented May 7, 2010 at 8:05

4 Answers 4

10

Here's an example:

$sentence = 'Today is a great day.';

// Only leave "word" characters and whitespace
$sentence = preg_replace('/[^\w\s]+/', '', strtolower($sentence));

// Tokenize
$tokens = explode(' ', $sentence);

for($i = 0; $i < count($tokens); $i++) {
    for($j = 1; $j <= count($tokens) - $i; $j++) {
        echo implode(' ', array_slice($tokens, $i, $j)) . "<br />";
    }
}

Output:

today
today is
today is a
today is a great
today is a great day
is
is a
is a great
is a great day
a
a great
a great day
great
great day
day
Sign up to request clarification or add additional context in comments.

5 Comments

+1 Easy to read and understand, i.e. not over-engineered :) This would, however, provide a great foundation for a game of code golf.
You might want to benchmark this with somewhat longer strings though. array_slice does not come cheap.
@jensgram feel free to initiate such a game :)
@salathe Hmmm, yeah. Tomorrow, maybe :)
@jensgram: aww, not everyone is around at the weekend :(
0

split it into an array of words using the php-function explode. Then use two nested loops. The outer one (i) goes through the array-indicies (0..count(array)-1) and is about the first word in the output line. The inner loop (j) goes from i+1 to the length of the array. Then inside the inner loop, you have to output the words from i to j-1. Use implode to do that. Use it on a subarray of the word array from i to j-1. You can get it using array_slice

Comments

0
$phrase = 'Today is a great day';
$pieces = explode(' ', strtolower($phrase));
$sets = array();
for ($i=0; $i<count($pieces);$i++) {
    for ($j=0; $j<count($pieces);$j++) {
        if ($i<=$j)
            $sets[$i][] = $pieces[$j];
    }
}
print "<ul>";
foreach($sets as $set) {
    while(count($set) > 0) {
        print "<li>" . implode(' ', $set) . "</li>\n";
        array_pop($set);
    }
}
print "</ul>";

Result:

  • today is a great day
  • today is a great
  • today is a
  • today is
  • today
  • is a great day
  • is a great
  • is a
  • is
  • a great day
  • a great
  • a
  • great day
  • great
  • day

Comments

0

Recursive approach:

function iterate($words) {
    if(($total = count($words)) > 0) {
        $str = '';
        for($i = 0; $i < $total; $i++ ) {
            $str .= ' ' . $words[$i];
            echo $str . PHP_EOL;
        }
        array_shift($words);
        iterate($words);
    }
}

$text = "Today is a great day.";
$words = str_word_count($text, 1);
iterate($words);

The above will only consider words. It will not remove duplicates. Numbers are not words and punctuation ain't either. With the given test sentence of five words, the recursive approach performs neglectably faster than the array_splice solution. However, this increases significantly with each additional word. A quick benchmark on my machine with a ten word sentence finished in almost half the time.


Disclaimer: Isolated Benchmarks depend on a number of factors and may produce different results on different machines. If anything, they can give an indicator about code performance (often in the realms of micro-optimzations), but nothing more.

Comments

Your Answer

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.