2010-10-28 2 views
3

Я нахожусь в середине изучения PHP, и возникла следующая проблема, связанная со списком. Язык не имеет большого значения, поэтому я дам вам это в псевдокоде. Разумеется, ответы на псевдокод отлично.Сокращение массива на основе последовательных вхождений

Скажем, существует список двух разных повторяющихся элементов - например, двух отдельных символов. Поэтому мой список выглядит примерно так:

myList = [C, C, D, C, D, D, D, C, C, D, C, D, C, C, ...] 

Однако это не та форма, которую я хочу. Вместо этого, список должен выглядеть следующим образом:

myList* = [CC, D, C, DDD, CC, D, C, D, CC, ...] 
myList* = shorten(myList) 

Какой самый элегантный способ превратить список односимвольный в один, который содержит непрерывные строки последующих символов в качестве ее элементов? Мое решение кажется мне довольно дерьмовым, учитывая, что оно включает в себя многократно вложенные if-утверждения, различные переменные состояния и другую гадость.

Pseudo-code прочь! Большое спасибо заранее за любую реализацию

shorten() 

вы бросаете меня.

ответ

0

Вы можете сделать это с помощью одного сканирования массива путем отслеживания текущего символа и последнего символа:

function shorten($myList) { 
     $myList[] = '';       // add a dummy char at the end of list. 
     $result = array();      // result to be returned. 
     $last_char = $myList[0];    // initilize last char read. 
     $combine = $last_char;     // initilize combined string. 
     for($i=1;$i<count($myList);$i++) {  // go from index 1 till end of array. 
       $cur_char = $myList[$i];  // current char. 
       if($cur_char != $last_char) { 
         $result[] = $combine; // time to push a new string into result. 
         $combine = $cur_char; // reset combine string. 
       } else { 
         $combine.=$cur_char; // is cur char is same as prev..append it. 
       } 
       $last_char = $cur_char;   // for next iteration cur become last. 
     } 
     return $result;       // return result. 
} 

Code In Action

0
$myList = array('C', 'C', 'D', 'C', 'D', 'D', 'D', 'C', 'C', 'D', 'C', 'D', 'C', 'C'); 

function shorten($list) { 
    $newList = array(); 

    foreach($list as $key => $entry) { 
     if ($key == 0) { 
      $newList[] = $entry; 
     } elseif ($entry == substr($newList[count($newList)-1],0,1)) { 
      $newList[count($newList)-1] .= $entry; 
     } else { 
      $newList[] = $entry; 
     } 
    } 

    return $newList; 
} 

$shortenedList = shorten($myList); 

var_dump($myList); 
echo '<br />'; 
var_dump($shortenedList); 
+0

Я считаю, что сортировки (список $) была ошибка .. –

+0

@Jan - начальная разночтений вопроса –

0
$result = array(); 
$word = ''; 
$lastChar = $myList[0]; 
foreach($myList as $char){ 
    if($lastChar !== $char){ 
     $result[] = $word; 
     $word = ''; 
    } 
    $word .= $char 
} 
2

Использование PHP 5.3 Закрытие и array_reduce:

ini_set('error_reporting', E_ALL); 

function shorten(array $list) { 
    return array_reduce($list, function($a, $b) { 
     $lastIdx = count($a) - 1; 
     if(isset($a[$lastIdx]) && strstr($a[$lastIdx], $b)) $a[$lastIdx] .= $b; 
     else $a[] = $b; 

     return $a; 
    }, array()); 
} 


$list = array('C', 'C', 'D', 'C', 'D', 'D', 'D', 'C', 'C', 'D', 'C', 'D', 'C', 'C'); 
$expected = array('CC', 'D', 'C', 'DDD', 'CC', 'D', 'C', 'D', 'CC'); 

$listShortened = shorten($list); 
assert($expected === $listShortened); 
+0

Вы можете Получать неопределенное смещение -1 на третьей строке кода, но мне очень нравится это решение. –

+0

@ [Jan Turoň] Ты меня достал. Правда, я немного изменил настройку уровня ошибки, чтобы исключить ошибки E_NOTICE. ;-) – Max

+0

@ [Jan Turoň] Я обновил код, добавил одну строку, но теперь он не проглатывает ошибки и не рассчитывает длину $ a дважды за итерацию. – Max

0

Немного короче альтернатива ответ Макса ...

$mylist = array("a","b","b","b","c","c","d"); 
function shorten($array) { 
    $str = implode("",$array); // step 1: make string from array of chars 
    preg_match_all("/(\w)\\1*/",$str,$matches); // step 2: split into chunks 
    return $matches[0]; // step 3: that's all 
} 
print_r(shorten($mylist)); 
Смежные вопросы