我的一位朋友得到了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;
}
}
答案 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)。要存储三个字符,请从字节中读取位(例如从左到右)。
*要略微改进压缩大小,如果你的字符串长度%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要好。