Java中的字符串压缩

Java中的字符串压缩,java,algorithm,performance,Java,Algorithm,Performance,我已经编写了一段压缩非数字字符字符串的代码。例如,“aabccccaaa”将压缩为a2b1c4a3。我想知道我实现这一点的方式是否有一个有效的渐进运行时。有没有更有效的方法来完成 代码如下: public static String Compress(String s) { if(s.length()<=2) { return s; } int org_length=s.length(); String comp=""; in

我已经编写了一段压缩非数字字符字符串的代码。例如,“aabccccaaa”将压缩为a2b1c4a3。我想知道我实现这一点的方式是否有一个有效的渐进运行时。有没有更有效的方法来完成

代码如下:

public static String Compress(String s)
{
    if(s.length()<=2)
    {
        return s;
    }
    int org_length=s.length();
    String comp="";
    int i=0;
    while(i<org_length)
    {
        Integer lc=1;
        while(i+1<org_length && s.charAt(i)==s.charAt(i+1))
        {
            lc++;
            i++;

        }
        if(i>=org_length){
            comp=comp+s.charAt(s.length()-1)+1;
        }
        else{
        comp=comp+s.charAt(i)+lc.toString();
        }

        i++;
    }
    if(s.length()<=comp.length())
    {
        return s;
    }
    return comp;
}
公共静态字符串压缩(字符串s)
{

如果(s.length()while计数器应比较组字符的开头,直到它发生变化或到达字符串结尾。然后只需写入组字符的开头和捕获的长度。复杂性应为O(n)

公共字符串压缩(字符串str){
StringBuilder res=新的StringBuilder();
int len=str.length();
对于(int i=0;i
(这是一个“更干净”的实现,主要是因为它隔离了边界值,但具有相同的总体复杂性,假设字符串串联是常量-希望很明显它只读取字符串一次。)

但是,只有在非常特定的情况下才有效-主要是当单个值重复多次时。与呈现的数据一样,它被压缩到80%,但“abababab”将“压缩”到原始值的200%

对于非常短的(~4+个字符)字符串可能是合适的:“Smaz是一个简单的压缩库,适合压缩非常短的字符串 字符串。”(它是为“类似英语的文本”定制的,因此可能不适合此数据。)


对于短字符串(~60+个字符),实现可能更实用。(一些DEFLATE实现在不需要时会创建一个无用的大字典;请确保检查实际的“压缩”大小,并允许使用替代或无压缩模式。)

对不起,你能澄清一下吗,你是在问你的运行长度编码方法是否有效,还是有更有效的方法来压缩字符串?我想两者都说,但如果我必须选择一种方法,那就是是否有更有效的方法来压缩字符串。如果你在寻找替代解决方案,过去已经有过多次讨论在堆栈交换上的压缩;搜索应该找到它们。当无法预测数据内容时,压缩数据的一种更有效的方法是Lempel Ziv Markov链压缩。还有@ElliottFrisch再次感谢!但是“abababab”会“压缩”200%的原始版本!显示了对运行长度编码的基本理解不足。在这种情况下,有些实现仍然会将其压缩并将其很好地压缩到
ab5
。运行长度编码不仅限于单字节重复,它也是一种适合多字节重复的技术,就像我我们已经在这里演示了。@JarrodRoberson这是一个有效点-这假设一个窗口只有一个字符。
public String rleCompress (String str) {
    StringBuilder res = new StringBuilder();
    int len = str.length();
    for (int i = 0; i < len;) {
       char c = str[i];
       int l = 0;
       // Always will loop at least once.
       while (i < len && str[i] == c) {
         l++;
         i++;
       }
       res.append(c);
       res.append(l);
    }
    return res.toString();
}