允许使用有限字符压缩java中的字符串

时间:2014-12-28 11:15:52

标签: java

我的一位朋友得到了interview question。此外,他被告知他可以假设这些字符是字母a到z(大写或小写)。我写了以下内容,但我无法弄清楚如何使用关于字符串包含的有限字符(a到z)的假设。我是在没有意识到的情况下使用这个假设,还是可以使用它?

  public static String compress(String str){
    int count = 1;
    char c = str.charAt(0);
    StringBuffer result = new StringBuffer();

    for (int i = 1; i < str.length();i++){
      if (str.charAt(i) == c){
        count++;
      }
      else{
        String to_add = c + String.valueOf(count);
        result.append(to_add);
        count = 1;
        c = str.charAt(i);
      }
    }
    // last character
    String to_add = c + String.valueOf(count);
    result.append(to_add);

    String result_str = result.toString();

    // Check whether the compressed string is
    // actually smaller than the original one
    if (result_str.length() < str.length()){
      return result_str;
    }
    else{
      return str;
    }
  }

2 个答案:

答案 0 :(得分:0)

'a'到'Z'是2*26=52个不同的字符,它适合6位(2^6=64)。你可以把代码点打包成六重奏。

OTOH,RLE(您编码的内容)仅适用于重复。如果你有像abcde这样的输入,它会变成1a1b1c1d1e或类似的东西,效率非常低,你很难称之为压缩。

答案 1 :(得分:0)

将每个字符分配给一个数字,例如a = 1,z = 26.因此,要表示这26个字符,您至少需要5位。

现在可以使用2个字节(16位)来存储三个字符。这需要比每个字符的初始一个字节少1/3的字节(如果是ascii)。要存储三个字符,请从字节中读取位(例如从左到右)。

  1. 第一个字节的前五位代表第一个字符
  2. 第一个字节的后三位与第二个字节的前两位连接表示第二个字节
  3. 第二个字节的后五位代表第三个字符
  4. 剩下一点(忽略它)
  5. *要略微改进压缩大小,如果你的字符串长度%3 = 1,那么对于你字符串的最后一个字符,你只能使用一个字节,因为你没有另一个三元组。

    **如果使用this post中的算法在字节上设置了特定位,则可以得到:

    public byte getBit(byte b, int position)
    {
       return (b >> position) & 1;
    }
    

    ***你可以使用this post中的算法将一个位设置为一个字节,它们是:

    设置一个位(将其设置为1)

    b = b | (1 << position);
    

    取消设置(将其设置为零):

    b = b & ~(1 << position);
    

    ****使用数学(5和8的最小公倍数),如果你使用5个字节= 40位,你甚至可以略微改善压缩大小,它可以代表8个字符(8x5 = 40)。

    然后你将存储字符的八位字节,现在没有可忽略的位。对于String的最后一个字符,取决于(字符串大小%8),您可以再次使用更少的字节。

    *****使用最后的5字节方法,您可以减少3/8的大小,这比3字节方法的1/3要好。