文件压缩
File Compression
我正在尝试通过将字符串转换为字母和数字来压缩它。示例:
INPUT: AAAAbbWWWW
OUTPUT: A4-b2-W4
这是我要运行解决的问题:
当我用 运行 查询 "aaaaaaa" 时,我得到 "a7".
当我用 运行 查询 "aaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbb" 时,我得到 "a12-b2-b2-b2-b2-b2-b2-b2-b2-b2-b2-b2-b2-b2-b2".
我的密码是
List<Character> chars = new ArrayList<Character>();
for (int i = 0; i < toCompress.length(); i++) {
chars.add(toCompress.charAt(i));
}
List<String> bits = new ArrayList<String>();
for (int i = 0; i < chars.size(); i++) {
char toMatch = chars.get(i);
int matching = 1;
for (int dontuse = i; dontuse < chars.size(); dontuse++) {
int x = dontuse + 1;
if (x >= chars.size()) {
continue;
}
if (chars.get(x) == toMatch && (x - 1 == matching)) {
matching++;
}
}
if (!bits.contains(toMatch + "" + matching)) {
bits.add(toMatch + "" + (matching + 1));
i = i + matching;
}
}
String compressed = "";
for (int y = 0; y < bits.size(); y++) {
if (y == (bits.size() - 1)) {
compressed += bits.get(y);
} else {
compressed += bits.get(y) + "-";
}
}
return compressed;
谁能告诉我如何阻止它在除第一个以外的每个片段中只数到二?
针对您的问题的简单算法如下:
private static String compress(String str) {
StringBuilder compressed = new StringBuilder();
int i = 0;
while (i < str.length()) {
int length = 1;
while (i < str.length() - 1 && str.charAt(i) == str.charAt(i+1)) {
length++;
i++;
}
compressed.append(str.charAt(i)).append(length).append('-');
i++;
}
return compressed.deleteCharAt(compressed.length() - 1).toString();
}
它是这样的:当索引 i
处的输入字符串的字符与后面的字符相同时,我们增加一个 length
。结果,length
等于后面相同字符的数量。
当我们击中不同的字符时,我们停止循环,存储当前字符及其长度,并为下一个字符再次重复所有这些。
请注意,此算法会将 "compress" 字符串 b
转换为 b1
。您没有指定它在此类字符串上的行为方式。如果您不想这样做,您可以在 length
附加到当前压缩字符串之前简单地添加一个检查。
好的,我修好了。这是我所做的:
List<Character> chars = new ArrayList<Character>();
List<Character> oChars = new ArrayList<Character>();
for (int i = 0; i < toCompress.length(); i++) {
chars.add(toCompress.charAt(i));
}
for (char c : chars) {
if (!oChars.contains(c)) {
oChars.add(c);
}
}
HashMap<Character, Integer> map = new HashMap<Character, Integer>();
for (int i = 0; i < chars.size(); i++) {
try {
map.put(chars.get(i), map.get(chars.get(i)) + 1);
} catch (NullPointerException ex) {
map.put(chars.get(i), 1);
}
}
String compressed = "";
for (char c : oChars) {
int amount = map.get(c);
compressed += c + "" + amount + "-";
}
StringBuilder b = new StringBuilder(compressed);
b.replace(compressed.lastIndexOf("-"), compressed.lastIndexOf("-") + 1, "" );
compressed = b.toString();
return compressed;
嗯,你的逻辑不成立。事实上,很难理解你在这里试图做什么。
添加到bits
的地方是重要的部分,因为最后你基本上显示了bits
中的内容。那么让我们看看那部分。
if (!bits.contains(toMatch + "" + matching)) {
bits.add(toMatch + "" + (matching + 1));
i = i + matching;
}
因此,重要的是要了解您在哪里更改了 matching
。
第一个循环针对 a
运行良好验证。但是你的问题是这样的:
if (chars.get(x) == toMatch && (x - 1 == matching)) {
matching
在内循环开始时为1。因此,一旦您进入超出 0 和 1 的 i
范围,x - 1
就不会等于 matching
,这意味着 matching
不会更改,它将停留在 1
.
所以除了你的第一个字符,你永远不会在 matching
中得到正确的数字,因为它永远不会递增。将 运行 索引与计数进行比较没有意义。
我正在尝试通过将字符串转换为字母和数字来压缩它。示例:
INPUT: AAAAbbWWWW
OUTPUT: A4-b2-W4
这是我要运行解决的问题:
当我用 运行 查询 "aaaaaaa" 时,我得到 "a7".
当我用 运行 查询 "aaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbb" 时,我得到 "a12-b2-b2-b2-b2-b2-b2-b2-b2-b2-b2-b2-b2-b2-b2".
我的密码是
List<Character> chars = new ArrayList<Character>();
for (int i = 0; i < toCompress.length(); i++) {
chars.add(toCompress.charAt(i));
}
List<String> bits = new ArrayList<String>();
for (int i = 0; i < chars.size(); i++) {
char toMatch = chars.get(i);
int matching = 1;
for (int dontuse = i; dontuse < chars.size(); dontuse++) {
int x = dontuse + 1;
if (x >= chars.size()) {
continue;
}
if (chars.get(x) == toMatch && (x - 1 == matching)) {
matching++;
}
}
if (!bits.contains(toMatch + "" + matching)) {
bits.add(toMatch + "" + (matching + 1));
i = i + matching;
}
}
String compressed = "";
for (int y = 0; y < bits.size(); y++) {
if (y == (bits.size() - 1)) {
compressed += bits.get(y);
} else {
compressed += bits.get(y) + "-";
}
}
return compressed;
谁能告诉我如何阻止它在除第一个以外的每个片段中只数到二?
针对您的问题的简单算法如下:
private static String compress(String str) {
StringBuilder compressed = new StringBuilder();
int i = 0;
while (i < str.length()) {
int length = 1;
while (i < str.length() - 1 && str.charAt(i) == str.charAt(i+1)) {
length++;
i++;
}
compressed.append(str.charAt(i)).append(length).append('-');
i++;
}
return compressed.deleteCharAt(compressed.length() - 1).toString();
}
它是这样的:当索引 i
处的输入字符串的字符与后面的字符相同时,我们增加一个 length
。结果,length
等于后面相同字符的数量。
当我们击中不同的字符时,我们停止循环,存储当前字符及其长度,并为下一个字符再次重复所有这些。
请注意,此算法会将 "compress" 字符串 b
转换为 b1
。您没有指定它在此类字符串上的行为方式。如果您不想这样做,您可以在 length
附加到当前压缩字符串之前简单地添加一个检查。
好的,我修好了。这是我所做的:
List<Character> chars = new ArrayList<Character>();
List<Character> oChars = new ArrayList<Character>();
for (int i = 0; i < toCompress.length(); i++) {
chars.add(toCompress.charAt(i));
}
for (char c : chars) {
if (!oChars.contains(c)) {
oChars.add(c);
}
}
HashMap<Character, Integer> map = new HashMap<Character, Integer>();
for (int i = 0; i < chars.size(); i++) {
try {
map.put(chars.get(i), map.get(chars.get(i)) + 1);
} catch (NullPointerException ex) {
map.put(chars.get(i), 1);
}
}
String compressed = "";
for (char c : oChars) {
int amount = map.get(c);
compressed += c + "" + amount + "-";
}
StringBuilder b = new StringBuilder(compressed);
b.replace(compressed.lastIndexOf("-"), compressed.lastIndexOf("-") + 1, "" );
compressed = b.toString();
return compressed;
嗯,你的逻辑不成立。事实上,很难理解你在这里试图做什么。
添加到bits
的地方是重要的部分,因为最后你基本上显示了bits
中的内容。那么让我们看看那部分。
if (!bits.contains(toMatch + "" + matching)) {
bits.add(toMatch + "" + (matching + 1));
i = i + matching;
}
因此,重要的是要了解您在哪里更改了 matching
。
第一个循环针对 a
运行良好验证。但是你的问题是这样的:
if (chars.get(x) == toMatch && (x - 1 == matching)) {
matching
在内循环开始时为1。因此,一旦您进入超出 0 和 1 的 i
范围,x - 1
就不会等于 matching
,这意味着 matching
不会更改,它将停留在 1
.
所以除了你的第一个字符,你永远不会在 matching
中得到正确的数字,因为它永远不会递增。将 运行 索引与计数进行比较没有意义。