我想计算一个字节列表中连续重复数字的数量,并将它们显示为两个整数数组:
因此,对于这样的输入:
Byte[] bytes = new Byte[] {2, 2, 2, 0, 0, 0, 0, 2, 2, 0, 0, 2};
我期望这样的输出:
integers -[2, 0, 2, 0, 2]
frequency -[3, 4, 2, 2, 1]
基本上,这是输入的压缩视图。输出显示整数2重复3次,然后是0,重复4次,然后是2重复2次,依此类推。
我写了下面的代码。
List<Byte> integers = new ArrayList<>();
List<Integer> frequencies = new ArrayList<>();
for (int i=0; i < bytes.size() - 1; i++) {
Byte current = bytes.get(i);
Byte next = bytes.get(i+1);
if (current == next) {
count ++;
// if all bytes are of the same type
if (count == bytes.size() || i == bytes.size() - 2) {
integers.add(current);
frequencies.add(count);
}
continue;
integers.add(current);
frequencies.add(count);
count = 1;
}
}
System.out.println("integers " + integers + " - frequency " + frequencies);
此代码适用于大多数情况。但是我缺少一些优势案例。就像示例输入一样,输出缺少到达最后一个元素2的值。我输入的代码输出是-
integers -[2, 0, 2, 0]
frequency -[3, 4, 2, 2]
我要添加一堆if
语句来涵盖所有极端情况,但我想知道是否有更清洁的解决方案?
答案 0 :(得分:1)
我没有尝试在IDE上运行此代码,但我认为这足够了:
int count = 1;
int index = 0;
byte current = bytes[index];
while (index < bytes.length - 1) {
index++;
if (bytes[index] == current) {
count++;
} else {
integers.add(current);
frequencies.add(count);
count = 1;
current = bytes[index];
}
}
integers.add(current);
frequencies.add(count);
答案 1 :(得分:0)
使用continue
是一个问题。
for (int i=0; i < bytes.size() - 1; i++) {
Byte current = bytes.get(i);
Byte next = bytes.get(i+1);
if (current == next) {
count ++;
// if all bytes are of the same type
if (count == bytes.size() || i == bytes.size() - 2) {
integers.add(current);
frequencies.add(count);
}
continue;
integers.add(current);
frequencies.add(count);
count = 1;
}
}
“ continue
”表示它将立即转到for循环的顶部。因此,continue
语句之后的几乎所有内容都是死代码-它永远不会执行,因为continue意味着“跳至for循环的下一个迭代”。因此,我们永远不会到达此代码:
integers.add(current);
frequencies.add(count);
count = 1;
话虽如此,您的逻辑也有一个缺陷。。它仅迭代到倒数第二个元素,因为它与下一个比较。也就是说,如果您输入的是[1、2、3],则迭代如下:
...就是这样。您将需要在循环外处理“最后一个数字”用例,或者更新循环以循环到最后(并适当地保护get(i+1)
调用。)当然,这仅在以下情况下才有意义最后一个数字和倒数第二个不同;如果是这样,则最后一个数字将被“计数”为前一个数字的重复。
答案 2 :(得分:0)
您可以使用此功能:
Byte[] bytes = new Byte[]{2, 2, 2, 0, 0, 0, 0, 2, 2, 0, 0, 2};
List<Byte> integers = new ArrayList<>();
List<Integer> frequencies = new ArrayList<>();
for (Byte b : bytes) {
if (integers.isEmpty() || !integers.get(integers.size() - 1).equals(b)) {
integers.add(b);
frequencies.add(0);
}
frequencies.set(frequencies.size() - 1, frequencies.get(frequencies.size() - 1) + 1);
}
结果将是:
integers [2, 0, 2, 0, 2]
frequency [3, 4, 2, 2, 1]
答案 3 :(得分:-2)
在for
中,您应该进行i < bytes.size()
我会详细说明:您只在最后一个元素之前运行,所以如果最后一个元素不同,那么您会错过他。
for (int i=0; i < bytes.size(); i++) {
Byte current = bytes.get(i);
// If the last byte is a single byte - then it is added with current byte and count = 1, which reseted in the previous step
// If it is consecutive value the count is correct from the increase in the previous step
if (i == bytes.size() - 1) {
integers.add(current);
frequencies.add(count);
} else {
Byte next = bytes.get(i+1);
if (current == next) {
count++;
} else {
integers.add(current);
frequencies.add(count);
count = 1;
}
}
}