【问题标题】:Loop array of bytes only for ones [closed]循环字节数组仅适用于[关闭]
【发布时间】:2016-04-05 07:54:48
【问题描述】:

我有一个字节数组。有些是 0,有些是 1。

import java.util.Arrays;

byte[] bytes = new byte[100];

我只想循环 1。如何做到这一点?

【问题讨论】:

  • 1 是什么意思?
  • 循环遍历数组并使用if 条件对1 进行处理。
  • 字节不是比特,如果你的意思是这样的话
  • 我不想在所有数组上循环,因为它的尺寸很大。我想循环数组中值为 1 的项目并丢弃值为 0 的项目
  • 你不能。如果你想过滤和排列你必须至少检查一次数组。这不能少于 o(n)。

标签: java arrays


【解决方案1】:

我不想在所有数组上循环,因为它的大小很大。我

实际上 100 个字节是微不足道的。它使用 2 个缓存行。但是,如果您想提高性能,您可以使用一个位集,每个 0 或 1 仅使用一位而不是 8。

BitSet bs = new BitSet(1 << 20); // 1 Mb
for(int i = 0; (i = bs.nextSetBit(i+1)) >= 0;)
    System.out.println("Next set bit is " + i);

这仍然需要循环遍历数据,但它可以一次检查 64 位。

【讨论】:

  • 如果数组非常大,我可以减少循环它的时间吗?
  • 谢谢彼得。我实际上并不是说 100 个项目,我有时大约有 100000000 个项目。BitSet 的代码是否会尽可能减少时间
  • @andolsizied 虽然测试存在缺陷,但根据具体情况,您可能是对的。 +1
【解决方案2】:

带有测试的 for 循环应该可以解决问题。

    BitSet bs = new BitSet(100000000); 
    for (int i = 0; i < 100000000; i++) {bs.set(i);}
    long stDate = System.currentTimeMillis();
    for (int i = 0; (i = bs.nextSetBit(i + 1)) >= 0;) {// TODO}
    long endDate = System.currentTimeMillis();
    System.out.println(endDate - stDate);

    byte[] bytes = new byte[100000000];
    for (int i = 0; i < 100000000; i++) {bytes[i] = 1;}
    stDate = System.currentTimeMillis();
    for (byte b : bytes) {  if (b == 1) // TODO}
    endDate = System.currentTimeMillis();
    System.out.println(endDate - stDate);

【讨论】:

  • 我怀疑您正在遭受大量死代码消除的困扰。顺便说一句 new Date().getTime()System.currentTimeMillis() 相同
  • 感谢指正,不影响结果。
猜你喜欢
  • 1970-01-01
  • 2019-01-29
  • 2021-02-23
  • 2014-12-13
  • 1970-01-01
  • 2013-06-02
  • 2015-04-26
  • 2012-12-11
  • 1970-01-01
相关资源
最近更新 更多