我有很长的整数序列,看起来像这样(任意长度!):
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');
};
答案 0 :(得分:7)
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;
}
答案 1 :(得分: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;
答案 2 :(得分: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);
});
}
答案 3 :(得分:0)
仅供参考,您可能会对您的数据进行gzip,浏览将自动解压缩。对于大多数实现,这将比RLE更好地工作。但显然不那么有趣。
答案 4 :(得分: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;
答案 5 :(得分: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;
}