Как получить длину самой длинной последовательности с одинаковыми символами в строке? - PullRequest
1 голос
/ 10 мая 2010

Указать:

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

Есть хорошие идеи?

Ответы [ 4 ]

11 голосов
/ 10 мая 2010
function getLength($str)
{
  if (''===$str) return 0;
  preg_match_all('!(.)\\1*!', $str, $m);
  return max(array_map('strlen', $m[0]));
}
9 голосов
/ 10 мая 2010
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;
}
4 голосов
/ 10 мая 2010

Вот мое мнение, которое должно работать несколько быстрее, чем Regex и substr предлагаемые решения:

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;
}

И так как это было забавное упражнение, я добавил небольшой класс поверх этого:

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());
    }
}

Это SplMaxHeap (требуется 5.3), что означает, что вы можете выполнить итерацию по нему, но при этом будут извлечены элементы из кучи, поэтому впоследствии она будет пустой:

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

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

Результат итерации будет

7 => eeeeeee
6 => dddddd
6 => ffffff
5 => ccccc
5 => ggggg
4 => hhhh
4 => bbbb
3 => iii
3 => aaa
2 => jj
1 => k
2 голосов
/ 10 мая 2010

Вы можете получить это довольно тривиально, перебирая строку по одному символу за раз, отслеживая последний ударенный вами символ и сколько раз вы его нажимали. Также храните наибольшее количество из них; когда вы нажимаете другого персонажа, проверьте, не достиг ли вы нового максимального количества последовательных символов, и, если это так, сохраните его как ваш новый максимум. Вернуть максимум, когда вы прошли всю строку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...