代码之家  ›  专栏  ›  技术社区  ›  Alex

重复整数序列的编码/压缩

  •  8
  • Alex  · 技术社区  · 15 年前

    我有很长的整数序列,看起来像这样(任意长度!)以下内容:

    0000000001110002220033333
    

    现在我需要一些算法把这个字符串转换成类似

    a9b3a3c3a2d5
    

    意思是“A 9次,B 3次,然后A 3次”等等,其中“A”代表0,“B”代表1,“C”代表2,“D”代表3。

    你会怎么做? 到目前为止,我还没有想到什么合适的,而且我在谷歌也没有运气,因为我真的不知道要搜索什么。这种编码/压缩称为什么?

    我要用 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');     
    };
    
    6 回复  |  直到 10 年前
        1
  •  7
  •   Yacoby    15 年前

    它被称为 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;
    }
    
        2
  •  2
  •   Arkh    15 年前

    这里是一个简单的实现您想要的东西。

    $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;
    
        3
  •  2
  •   Pointy    15 年前

    下面是一个较短的版本:

    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);
      });
    }
    
        4
  •  0
  •   James Westgate    15 年前

    仅供参考,您可能可以gzip您的数据,浏览将自动解压缩它。对于大多数实现来说,这将比RLE更好地工作。但显然没那么有趣。

        5
  •  0
  •   Félix Saparelli    14 年前
    $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;
    
        6
  •  0
  •   Harish Lalwani    10 年前
    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;
    

    }