2010-04-02 44 views
7

我有這個樣子很長整型序列的序列(任意長度!):編碼/壓縮重複整數

0000000001110002220033333 

現在我需要一些算法,這個字符串轉換成一些壓縮像

a9b3a3c3a2d5 

這意味着「a 9次,然後b 3次,然後3次」等等,其中「a」代表0,「b」代表1,「c」代表2,「d」代表3。

你會怎麼做? 到目前爲止,沒有什麼合適的東西出現在我的腦海裏,而且我對谷歌沒有好運,因爲我真的不知道要搜索什麼。這種編碼/壓縮稱爲什麼?

PS:我打算用PHP進行編碼,而在的解碼中使用JavaScript

編輯:謝謝大家!

我結束了此功能編碼:

protected function numStringToRle($s){   
     $rle = ''; 
     $count = 1; 
     $len = strlen($s); 
     for($i = 0; $i < $len; $i++){ 
      if($i != $len && isset($s[$i+1]) && $s[$i] == $s[$i+1]){ 
       $count++;     
      } else { 
       $rle .= chr($s[$i] + 97).($count == 1 ? '' : $count);         
       $count = 1; 
      } 
     } 
     return $rle;    
} 

而且,對於解碼:

var decodeCoords = function(str) { 

    str = str.replace(/(.)(\d+)/g, function(_, x, n) { 
     return new Array(parseInt(n, 10) + 1).join(x); 
    }); 

    return str. 
    replace(/a/g, '0'). 
    replace(/b/g, '1'). 
    replace(/c/g, '2'). 
    replace(/d/g, '3');  
}; 
+1

你到底是用這個做什麼?你確定你不能用Gzip壓縮它嗎? HTTP://計算器。com/questions/294297/javascript-implementation-of-gzip 這將會更加有效的時間和空間明智的,它已經爲你完成。 – ryeguy 2010-04-02 13:20:56

+0

gzip不是一個選項,因爲我需要用javascript解碼。我使用它作爲2D遊戲的一種掩碼。 – Alex 2010-04-02 13:27:46

回答

7

它被稱爲Run Length Encoding

基本編碼器在PHP中:

function numStringToRle($s){ 
    $rle = ''; 
    $count = 1; 
    $len = strlen($s); 
    for ($i = 0; $i < $len; $i++){ 
     if ($i != $len && $s[$i] == $s[$i+1]){ 
      $count++;     
     }else{ 
      $rle .= chr($s[$i] + 97).$count;  
      $count = 1; 
     } 
    } 
    return $rle; 
} 

被警告這將瓶坯不好。如果你將要如何處理可能有很多獨立的單個字符,你會得到更好的字符串添加一些複雜性和不寫長度與像

123456789123456789 

字符串問題如果運行的長度是1.

//change 
$rle .= chr($s[$i] + 97).$count;  

//to 
$rle .= chr($s[$i] + 97).($count == 1 ? '' : $count); 

//or 
$rle .= chr($s[$i] + 97) 
if ($count != 1){ 
    $rle .= $count; 
} 
+0

工程就像一個魅力,thx! – Alex 2010-04-02 14:19:55

+0

我在找這個算法的名字。謝謝! – Jack 2014-06-11 17:34:41

2

這是一個天真的實現你想要什麼。

$toEncode = '0000000001110002220033333'; 
$currentChar = '-1'; 
$length = strlen($toEncode); 
$encoded = ''; 
$currentNbrChar = 0; 
for($i = 0; $i < $length; $i++){ 
    if($toEncode[$i] != $currentChar){ 
    if($currentChar != '-1'){ 
     $encoded .= chr(97 + $currentChar).$currentNbrChar; 
    } 
    $currentNbrChar = 0; 
    $currentChar = $toEncode[$i]; 
    } 
    $currentNbrChar ++; 
} 
if($currentChar != '-1'){ 
    $encoded .= chr(97 + $currentChar).$currentNbrChar; 
} 
echo $encoded; 
+0

謝謝!這工作完美。 – Alex 2010-04-02 13:25:37

2

這裏有一個較短的版本:

function smush(str) { 
    return str.replace(/((.)\2*)/g, function(_, w, x) { 
    return x + w.length; 
    }); 
} 

編輯哦,我看你想用PHP編碼;對不起,我不知道。下面是一個類似的精神解碼器:

function unsmush(str) { 
    return str.replace(/(.)(\d+)/g, function(_, x, n) { 
    return new Array(parseInt(n, 10) + 1).join(x); 
    }); 
} 
0

僅供參考,你很可能gzip壓縮您的數據和瀏覽將自動解壓縮。對於大多數實現來說,這將比RLE更好地工作。顯然不那麼有趣。

0
$str="0000000001110002220033333"; 

//$c will count the number of occurances. 

$c=1; 

$lastInt=substr($str,0,1); 

$str=substr($str,1); 

$resultStr=''; 

$loopEnd=strlen($str); 


for($i=1; $i<=$loopEnd+1;$i++) 

{ 

    $nowInt=substr($str,0,1); 
    if($lastInt==$nowInt) 
    { 
     $c++; 
     $str=substr($str,1); 
    } 
    else 
    { 
     $char=chr((int)$lastInt + 97); 
     $resultStr=$resultStr.$char.$c; 
     $str=substr($str,1); 
     $c=1; 
     $lastInt=$nowInt; 
    } 
} 

// we use if condition since for loop will not take the last integer if it repeats. 

if($c>1) 
{ 

$char=chr((int)$lastInt + 97); 

$resultStr=$resultStr.$char.$c; 

} 

echo $resultStr; 
0
function compress($str) { 
$strArr = str_split($str.'0'); 
$count = 0; 
$resStr = ''; 
$strCheck = $strArr[0]; 
foreach($strArr as $key => $value) 
{ 
    if($strCheck == $value) 
    { 
     $count++; 
    } 
    else 
    { 
     if($count == 1) 
     { 
      $strCheck = $value; 
      $resStr .= $strArr[$key-1]; 
      $count=1; 
     } 
     elseif($count == 2) 
     { 
      $strCheck = $value; 
      $resStr .= $strArr[$key-1].$strArr[$key-1]; 
      $count=1; 
     } 
     else 
     { 
      $strCheck = $value; 
      $resStr .= $strArr[$key-1].$count; 
      $count=1; 
     } 
    } 

} 
return $resStr; 

}