【问题标题】:Shortening an array based on consecutive occurrences根据连续出现缩短数组
【发布时间】:2010-10-28 16:07:44
【问题描述】:

我正在学习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()

你扔给我。

【问题讨论】:

    标签: php arrays algorithm


    【解决方案1】:

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

    【讨论】:

    • 您可能会在代码的第三行收到未定义的偏移量 -1,但我非常喜欢这个解决方案。
    • @[Jan Turoň] 你找到我了。没错,我通过设置错误级别来排除 E_NOTICE 错误有点作弊。 ;-)
    • @[Jan Turoň] 我更新了代码,添加了一行,但现在它不会吞下错误,并且每次迭代不计算 $a 的长度。
    【解决方案2】:

    您可以通过跟踪当前字符和最后一个字符来对数组进行一次扫描:

    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

    【讨论】:

      【解决方案3】:
      $result = array();
      $word = '';
      $lastChar = $myList[0];
      foreach($myList as $char){
          if($lastChar !== $char){
              $result[] = $word;
              $word = '';
          }
          $word .= $char
      }
      

      【讨论】:

        【解决方案4】:
        $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);
        

        【讨论】:

          【解决方案5】:

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2019-11-14
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-10-28
            相关资源
            最近更新 更多