基于连续出现缩短数组

时间:2010-10-28 16:07:44

标签: php arrays algorithm

我正在学习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 个答案:

答案 0 :(得分:2)

使用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);

答案 1 :(得分: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

答案 2 :(得分: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);

答案 3 :(得分:0)

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

答案 4 :(得分:0)

比Max的答案稍微短一些......

$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));