压缩和解压缩字符串

时间:2012-11-29 21:05:11

标签: java c string

如何将“aaabbbc”之类的字符串压缩为“a3b3c”并对其进行解压缩,而不在处理期间使用额外的内存,主要是在C中以及在Java中?

3 个答案:

答案 0 :(得分:1)

要进行就地编码,编码的字符串绝不能长于原始字符串。假设我们假设以下编码规则:

  • 原始字符串中没有数字(因此不需要计数分隔符)
  • 永远不会明确编码1的运行长度(因此abc仍为abc

我相信通过这些假设,游程编码不会模糊,并且永远不会长于字符串本身。然后,以下算法(伪代码)应该完成编码工作:

currentChar ← string[0]
nextOutputPos ← 1
nextReadPos ← 1
count ← 1
while (nextReadPos < length of string) {
    nextChar ← string[nextReadPos++];
    if (nextChar == currentChar) {
        count++;
    } else {
        if (count > 1) {
            write (count as a string) to string at position nextOutputPos
            nextOutputPos ← nextOutputPos + (length of count as a string)
        }
        string[nextOutputPos++] ← currentChar ← nextChar;
    }
}

最后,编码的字符串包含在nextOutputPos的半开放范围[0,string)中。

答案 1 :(得分:1)

简单的反向扫描确实至少为编码部分提供了(看似)良好的解决方案。我正在从右到左进行一次扫描,并用出现次数覆盖字符串的部分。

char * enc(char * ip)
{
    int r,op;
    int l=strlen(ip);
    r=l-1;
    char curr;
    op=r;
    int curr_count=1,mod_curr_count;
    while(r>=0)
    {
        curr=ip[r];

        while(ip[--r]==curr)
        {

            curr_count++;
        }
        if(curr_count!=1)
        {
            while(curr_count)
            {
            mod_curr_count=curr_count%10;
            ip[op--]=(char)(mod_curr_count+48);
            curr_count/=10;
            }
            ip[op--]=curr;
            curr_count=1;

        }
        else
        {
        ip[op--]=curr;
        }
    }

    ip=ip+op+1;
    return ip;
}

输入: aaaaaaaaaaaabbbfffffffffffffffqqqqqqqqqqqqqqqqqqccccpoii

输出:a12b3f15q18c4poi2

答案 2 :(得分:0)

这是Java中的一种可能性,它使用了正则表达式:

String str = "aaabbbc";  // string to be encoded

StringBuilder sb = new StringBuilder();  // to hold encoded string

for (String s : str.split("(?<=(.))(?!\\1)")) {
    sb.append(s.charAt(0));
    if (s.length() > 1) // only append length if it's > 1
        sb.append(s.length());
}

System.out.println(sb.toString());
a3b3c