php中的字符串压缩

php中的字符串压缩,php,Php,这是我的意见 aaaabbaaaababbbcccccccccccc 这是我的预期输出 a4b2a4b1a1b3c12 我试着做foreach,然后concating计算值。这看起来很残忍。有没有什么方法可以在php中有效地实现这一点 帮助pls您可以使用正则表达式获得结果 preg_match_all('/(.)\1*/', $str, $m, PREG_SET_ORDER); $m = array_map(function($i) { return $i[1] . strlen($i[0

这是我的意见

aaaabbaaaababbbcccccccccccc
这是我的预期输出

a4b2a4b1a1b3c12
我试着做
foreach
,然后
concating
计算值。这看起来很残忍。有没有什么方法可以在php中有效地实现这一点


帮助pls

您可以使用正则表达式获得结果

preg_match_all('/(.)\1*/', $str, $m, PREG_SET_ORDER);
$m = array_map(function($i) { return $i[1] . strlen($i[0]); } , $m);
echo implode('', $m);   // a4b2a4b1a1b3c12

下面是一个如何使用几个for循环(编码和解码)的示例:

输出:

input =         'aaaabbaaaababbbcccccccccccc'
encoded =       'a4b2a4b1a1b3c12'
decoded =       'aaaabbaaaababbbcccccccccccc'
class SillyEncoding
{
    private static $digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

    static function encode($string)
    {
        $output = '';

        if (strlen($string) > 0) {
            $count = 0;
            $char = $string[0];

            for ($i = 0; isset($string[$i]); ++$i) {
                if (isset(self::$digits[$string[$i]])) {
                    throw new \InvalidArgumentException(sprintf('The input string must not contain a digit at offset %d, got "%s"', $i, $string[$i]));
                }

                if ($string[$i] === $char) {
                    ++$count;
                } else {
                    $output .= "{$char}{$count}";
                    $count = 1;
                    $char = $string[$i];
                }

                if (!isset($string[$i + 1])) {
                    $output .= "{$char}{$count}";
                }
            }
        }

        return $output;
    }

    static function decode($string)
    {
        $output = '';
        $length = strlen($string);

        if ($length > 0) {
            $char = $string[0];
            $count = null;

            if ($length < 2) {
                throw new \InvalidArgumentException(sprintf('Input string must be empty or at least 2 bytes long, got %d bytes', $length));
            }

            if (isset(self::$digits[$string[0]])) {
                throw new \InvalidArgumentException(sprintf('Input string must not start with a digit, got "%s"', $string[0]));
            }

            for ($i = 1; isset($string[$i]); ++$i) {
                $isDigit = isset(self::$digits[$string[$i]]);

                if ($isDigit) {
                    $count .= $string[$i];
                }

                if (!$isDigit || !isset($string[$i + 1])) {
                    if (null === $count) {
                        throw new \InvalidArgumentException(sprintf('Expected a digit at offset %d, got "%s"', $i, $string[$i]));
                    }

                    $count = (int) $count;

                    for ($j = 0; $j < $count; ++$j) {
                        $output .= $char;
                    }

                    $char = $string[$i];
                    $count = null;
                }
            }
        }

        return $output;
    }
}
SillyEncoding的
类:

input =         'aaaabbaaaababbbcccccccccccc'
encoded =       'a4b2a4b1a1b3c12'
decoded =       'aaaabbaaaababbbcccccccccccc'
class SillyEncoding
{
    private static $digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

    static function encode($string)
    {
        $output = '';

        if (strlen($string) > 0) {
            $count = 0;
            $char = $string[0];

            for ($i = 0; isset($string[$i]); ++$i) {
                if (isset(self::$digits[$string[$i]])) {
                    throw new \InvalidArgumentException(sprintf('The input string must not contain a digit at offset %d, got "%s"', $i, $string[$i]));
                }

                if ($string[$i] === $char) {
                    ++$count;
                } else {
                    $output .= "{$char}{$count}";
                    $count = 1;
                    $char = $string[$i];
                }

                if (!isset($string[$i + 1])) {
                    $output .= "{$char}{$count}";
                }
            }
        }

        return $output;
    }

    static function decode($string)
    {
        $output = '';
        $length = strlen($string);

        if ($length > 0) {
            $char = $string[0];
            $count = null;

            if ($length < 2) {
                throw new \InvalidArgumentException(sprintf('Input string must be empty or at least 2 bytes long, got %d bytes', $length));
            }

            if (isset(self::$digits[$string[0]])) {
                throw new \InvalidArgumentException(sprintf('Input string must not start with a digit, got "%s"', $string[0]));
            }

            for ($i = 1; isset($string[$i]); ++$i) {
                $isDigit = isset(self::$digits[$string[$i]]);

                if ($isDigit) {
                    $count .= $string[$i];
                }

                if (!$isDigit || !isset($string[$i + 1])) {
                    if (null === $count) {
                        throw new \InvalidArgumentException(sprintf('Expected a digit at offset %d, got "%s"', $i, $string[$i]));
                    }

                    $count = (int) $count;

                    for ($j = 0; $j < $count; ++$j) {
                        $output .= $char;
                    }

                    $char = $string[$i];
                    $count = null;
                }
            }
        }

        return $output;
    }
}
class-silly编码
{
私有静态$digits=[0,1,2,3,4,5,6,7,8,9];
静态函数编码($string)
{
$output='';
如果(strlen($string)>0){
$count=0;
$char=$string[0];
对于($i=0;isset($string[$i]);++$i){
if(isset(self::$digits[$string[$i]])){
抛出new\InvalidArgumentException(sprintf('输入字符串不能包含偏移量%d处的数字,获取“%s”,$i,$string[$i]);
}
如果($string[$i]==$char){
++$count;
}否则{
$output.=“{$char}{$count}”;
$count=1;
$char=$string[$i];
}
如果(!isset($string[$i+1])){
$output.=“{$char}{$count}”;
}
}
}
返回$output;
}
静态函数解码($string)
{
$output='';
$length=strlen($string);
如果($length>0){
$char=$string[0];
$count=null;
如果($length<2){
抛出new\InvalidArgumentException(sprintf('输入字符串必须为空或至少2字节长,获得%d字节',$length));
}
if(isset(self::$digits[$string[0]])){
抛出new\InvalidArgumentException(sprintf('输入字符串不能以数字开头,获取“%s”,$string[0]);
}
对于($i=1;isset($string[$i]);++$i){
$isDigit=isset(self::$digits[$string[$i]]);
如果($isDigit){
$count.=$string[$i];
}
if(!$isDigit | |!isset($string[$i+1])){
如果(null==$count){
抛出new\InvalidArgumentException(sprintf('在偏移量%d处需要一个数字,得到了“%s”,$i,$string[$i]);
}
$count=(int)$count;
对于($j=0;$j<$count;++$j){
$output.=$char;
}
$char=$string[$i];
$count=null;
}
}
}
返回$output;
}
}

需要注意的几点:

  • 这不是一个有效的压缩算法-如果有许多重复字符,它可能会减小大小,但如果您向其提供“正常”文本,则输出将是输入大小的两倍
  • 输入不能包含任何数字(OP:“输入将严格使用字母表”)
  • $str=str_split('aaaabbaababbcccccc');
    $count=0;
    $a=$result=$b='';
    对于($i=0;$i 0){
    $b.=$result;
    }
    $count=1;
    $a=$str[$i];
    $result=$a.$count;
    }
    }
    印刷品(乙元);;
    

    请参见

    downvote的原因是什么?请添加您尝试使用的代码好的,我将用我迄今为止使用的代码更新问题您是否有兴趣为这个特定字符串进行编程练习?或者你真的想要一个通用的压缩算法?如果输入本身包含数字怎么办?压缩字符串
    12
    是指
    11
    还是
    12
    ?谢谢,如果您解释我如何在for loop中执行此操作,会很有帮助。您希望替换数组映射到loop吗?或者关于你的问题是什么?是的,只是想知道如果我做循环
    foreach($m as&$i)$i=$i[1]会是什么样子。斯特伦($i[0])