Сокращение массива на основе последовательных вхождений - PullRequest
3 голосов
/ 28 октября 2010

Я нахожусь в процессе изучения 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, различные переменные состояния и другие неприятности.

Псевдокод прочь! Заранее большое спасибо за любую реализацию

shorten()

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

Ответы [ 5 ]

2 голосов
/ 28 октября 2010

Использование PHP 5.3 Closure и 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 голосов
/ 28 октября 2010

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

$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));
0 голосов
/ 28 октября 2010
$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 голосов
/ 28 октября 2010
$result = array();
$word = '';
$lastChar = $myList[0];
foreach($myList as $char){
    if($lastChar !== $char){
        $result[] = $word;
        $word = '';
    }
    $word .= $char
}
0 голосов
/ 28 октября 2010

Это можно сделать с помощью одного сканирования массива, отслеживая текущий символ и последний символ:

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

Код в действии

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