2010-10-28 39 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語句,各種狀態變量和其他問題。

僞代碼!非常感謝任何實施

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

我認爲,排序($列表)是一個錯誤.. – 2010-10-28 16:35:41

+0

@Jan - 這個問題初始誤讀 – 2010-10-28 16:50:04

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在代碼的第三行,但我非常喜歡這個解決方案。 – 2010-10-28 17:10:37

+0

@ [JanTuroň]你找到了我。誠然,我通過設置錯誤級別來排除E_NOTICE錯誤而欺騙了一下。 ;-) – Max 2010-10-28 17:12:48

+0

@ [JanTuroň]我更新了代碼,添加了一行,但現在它不會吞下錯誤,並且不會每次迭代計算兩次$ a的長度。 – Max 2010-10-28 17:16:13

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