我的一次采访中有这个问题:
给定一个字符串你会如何压缩它?
示例输入的格式不是aabbccdd
,而是abcdgehrk
。即chars
中的所有string
都不同。(注意:运行长度编码不起作用,因为它是我给出的解决方案之一,但他说字符串没有任何重复字符)
我给出了以下两种解决方案,但他不接受这些解决方案:
1)HashCode不能成为解决方案,因为它会存储数字
2)不能以二进制形式存储,因为它不是人类可读的格式
任何人都可以建议这个问题可能是另一种解决方案吗?
答案 0 :(得分:4)
鉴于审查员要求压缩字符串是人类可读的,一个解决方案是Run-Length Encoding。
因此,aabbccdd将被压缩为2a2b2c2d,而abcdgehrk将被压缩为1a1b1c1d1g1e1h1r1k。请注意,这些特殊示例中的输出字符串不短于原始字符串,但它是所有无损压缩算法的属性,它们无法保证对任何输入数据集进行压缩。
答案 1 :(得分:1)
如果要求允许字符串仅由小写字母字符组成,则每个字符可以适合5位(2 ^ 5 = 32个可能的字符)。然后,一个8个字符的字符串可以适合40位= 5个字节。
这是一个例子,将3个字符装入2个字节:
a = 00001
b = 00010
c = 00011
字符串" cab"适合:
c a b (extra bit)
00011 00001 00010 0
00011000 01000100
以big-endian形式:
0x1844
人类可读的要求很愚蠢。对于任何这种性质的东西,都需要软件和标准(例如ASCII)才能被人阅读。使用合适的软件和输出设备,任何东西都是人类可读的。
答案 2 :(得分:0)
我之前已经解决了这个问题,我将包含字符串,例如(aaabb),此过程将变为(a3b1),然后我将检查包含字符串的长度是否小于原始字符串的长度,我将返回包含字符串否则返回原始 (ab)->(a1b1)在这种情况下,我将返回原始字符串。 (aaaaabb)->(a5b2)在这种情况下,我将返回包含字符串。 这是我的代码,需要O(N)
public static String stringCompression(String str){
StringBuilder compressed = new StringBuilder();
int count = 1;
int i = 0;
for ( i = 0; i <str.length()-1 ; i++) {
if(str.charAt(i) == str.charAt(i+1)){
// System.out.println("str.charAt(i) = " + str.charAt(i));
count++;
}
else {
compressed.append(str.charAt(i)).append(count);
count =1;
}
}
if(i == str.length()-1)
compressed.append(str.charAt(i)).append(count);
return compressed.length() < str.length() ? new String(compressed): str;
}
您可能会使用此算法反解析数据
public static String stringDeCompression(String str){
StringBuilder stringBuilder = new StringBuilder();
int temp = 0;
int k = 0;
for (int i = 1; i <str.length() ; i+=2) {
temp = Character.getNumericValue(str.charAt(i));
for (int j = 0 ; j < temp ; j++) {
stringBuilder.append(str.charAt(k));
}
k+=2;
}
return new String(stringBuilder);
}