tags:

views:

144

answers:

4

To be specified:

function getLength($str)
{
   //function i need
}
$str1 = 'aabbcccc'; 
$str2 = 'aabbccccaaaaa';
echo getLength($str1); //will get 4
echo getLength($str2); //will get 5

Any good ideas?Thanks in advance!

+8  A: 
function getLongestSequence($str)
{
   $sl = strlen($str);
   $longest = 0;
   for($i = 0; $i < $sl; )
   {
       $substr = substr($str, $i);
       $len = strspn($substr, $substr{0});
       if($len > $longest)
           $longest = $len;
       $i += $len;
   }

   return $longest;
}
ThiefMaster
Aw man, you're no fun. You gave it away. :-(
Platinum Azure
...But I see my mistake now. Your solution is cleaner than mine... I'd forgotten strspn. Nicely done. +1
Platinum Azure
thanks for this nice solution.
SpawnCxy
You could save a little time by leaving the $i++ out of the loop and just adding $i += $len within the loop. Then you'll have fewer iterations.
Platinum Azure
yeah that's right.thanks for the note.
SpawnCxy
+2  A: 

You can get this rather trivially by iterating through the string one character at a time, keeping track of the last character you had hit and how many times you had hit it. Also store the largest number of those; when you hit a different character, check to see if you have hit a new maximum consecutive character count, and if so, store that as your new maximum. Return the maximum when you've gone through the entire string.

Platinum Azure
+5  A: 
function getLength($str)
{
  if (''===$str) return 0;
  preg_match_all('!(.)\\1*!', $str, $m);
  return max(array_map('strlen', $m[0]));
}
VolkerK
nice simple one!
SpawnCxy
+3  A: 

Here is my take on it, which should perform somewhat faster than the Regex and the substr solutions offered:

function getLongestSequenceLength($string)
{
    $longest = $i = 0;
    $totalLength = strlen($string);
    while($i < $totalLength) {
        if(($length = strspn($string,  $string[$i], $i)) > $longest) {
            $longest = $length;
        }
        $i += $length;
    }
    return $longest;
}

And since this was a fun exercise I've added a little class on top of that:

class Sequencer extends SplMaxHeap
{
    public function compare($a, $b) {
       return parent::compare(strlen($a), strlen($b));
    }
    public function key() {
        return strlen($this->current());
    }
    public function parseString($string)
    {
        $i = 0;
        $totalLength = strlen($string);
        while($i < $totalLength) {
            $length = strspn($string,  $string[$i], $i);
            $this->insert(str_repeat($string[$i], $length));
            $i += $length;
        }
    }
    public function getMaxLength()
    {
        $this->rewind();
        return strlen($this->top());
    }
}

That's an SplMaxHeap (requires 5.3), which means you can iterate over it but doing so will extract the elements from the Heap, so it will be empty afterwards:

$sequencer = new Sequencer;
$sequencer->parseString('aaabbbbcccccddddddeeeeeeeffffffggggghhhhiiijjk');

echo $sequencer->getMaxLength(); // 7
foreach($sequencer as $length => $sequence) {
    echo "$length => $sequence\n";
}
echo $sequencer->getMaxLength(); // RuntimeException

The result of the iteration will be

7 => eeeeeee
6 => dddddd
6 => ffffff
5 => ccccc
5 => ggggg
4 => hhhh
4 => bbbb
3 => iii
3 => aaa
2 => jj
1 => k
Gordon