首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在Java中删除数组中的负数

在Java中删除数组中的负数
EN

Stack Overflow用户
提问于 2016-11-07 01:31:12
回答 6查看 26.2K关注 0票数 20

我的目标是在Java中删除数组中的所有负数。

我已经写了下面的代码。我如何提高代码的复杂性,或者有一个好的算法?

代码语言:javascript
复制
public static void main(String[] args) {
    int[] array = { 1, -3, 4, -9, 3, 4, 70, -10, 0, 7 };
    System.out.println(Arrays.toString(removeNegativeNumbers(array)));
}

public static int[] removeNegativeNumbers(int[] num) {
    List<Integer> list = new ArrayList<>();
    for (int n : num) {
        if (n >= 0) {
            list.add(n);
        }
    }
    int[] result = new int[list.size()];
    for (int i = 0; i < result.length; i++) {
        result[i] = list.get(i).intValue();
    }
    return result;
}
EN

回答 6

Stack Overflow用户

发布于 2016-11-07 03:49:38

Java 8 streams怎么样?

代码语言:javascript
复制
Arrays.stream(num).filter(s -> s >= 0).toArray();
票数 52
EN

Stack Overflow用户

发布于 2016-11-07 07:10:13

我认为在效率方面,我们不能比@kaidul伊斯拉姆答案(和@user6904265的简洁性)更好了。

我只是添加了一个解决方案,它在一个非常特殊的场景中应该有一些价值,在这种场景中,负值很少出现,并且数组非常大。

基本思想是推迟实际复制,直到找到负值,然后使用System.arraycopy复制。如果没有找到负数组,则返回源数组。

代码语言:javascript
复制
import java.util.*;

public class NotNegativeTest {

    public static void main(String[] args) {
         int[] array = { 1, -3, 4, -9, 3, 4, 70, -10, 0, 7 }; 
         System.out.println(Arrays.toString(removeNegativeNumbers(array))); 
    } 

    public static int[] removeNegativeNumbers(int[] num) {
         int[] output = new int[num.length];
         int k = 0;
         int i = 0; 
         int last=-1;
         int howmany=0;

         while(i < num.length) {
             if(num[i] < 0) {
                howmany=i-last-1;
                switch(howmany) {
                    case 0: break;
                    case 1: 
                            output[k]=num[last+1];
                            k++;
                            break;
                    default:        
                            System.arraycopy(num, last+1,  output, k, howmany);
                            k+=howmany;
                }
                last=i;
             } 
             i++;
         } 
         if (last>=0) {
              if(last!=i-1) {
                howmany=i-last-1;  
                System.arraycopy(num, last+1,  output, k, howmany);
                k+=howmany;
            }
        } else {
            return num;
        }

         return Arrays.copyOfRange(output, 0, k);
     }

}

我已经找到时间来编写JMH微基准测试。

我使用过以下配置:

代码语言:javascript
复制
Options opts = new OptionsBuilder()
  .include(MyBenchmark.class.getSimpleName())
  .mode(Mode.AverageTime)
  .warmupIterations(1)
  .warmupTime(TimeValue.seconds(5))
  .measurementIterations(10)
  .measurementTime(TimeValue.seconds(5))
  .jvmArgs("-server")
  .forks(1)
  .build();
new Runner(opts).run();

(免责声明:我的第一个JMH测试,所以如果有人有什么建议,我很乐意更改它并更新结果)

结果如下:

代码语言:javascript
复制
# Run complete. Total time: 00:02:54

Benchmark                             Mode  Cnt  Score   Error  Units
MyBenchmark.testMethodUser6904265     avgt   10  0,201 ± 0,040   s/op
MyBenchmark.testMethodInsac           avgt   10  0,093 ± 0,022   s/op
MyBenchmark.testMethodKaidul          avgt   10  0,124 ± 0,029   s/op

现在,在为我欢呼之前,请先看看这个测试有多偏颇:

代码语言:javascript
复制
 int[] array = new int[10000000];
 array[0]=-5;
 array[10000]=-3;
 array[40000]=-3;
 array[8000000]=-3;

 int[] answer=NotNegativeTest.removeNegativeNumbers(array);

因此,这里需要注意的不是我的方法获胜(测试是为我的方法获胜而写的:-),而是即使在这种极端的情况下,泛型kaidul伊斯拉姆方法与我的方法是多么接近。

更新:这里是jmh benchmark I wrote的链接,这样你可以验证更真实的场景(如果有人发现我如何设置测试的问题,请让我知道)。在我对另一个答案的测试中,有一个对Trove的依赖性。

票数 9
EN

Stack Overflow用户

发布于 2016-11-07 01:35:31

这将通过一次迭代就地完成:

保存两个索引:原始数组上的srcdst。两者都被初始化为0。

当数字为正数时,将其从num[src]复制到num[dst],并使两个索引都前进

当数字为负数时,只需前进src

返回新大小为dst的原始数组。

代码语言:javascript
复制
public static int removeNegativeNumbers(int[] num) {
  int dst=0;
  for (int src=0 ; src<num.length ; ++src)
    if (num[src]>=0)
      num[dst++] = num[src];
  return dst;
}
票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40452330

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档