当前位置: 首页 > 知识库问答 >
问题:

在JAVA中比较和计算5个不同计数变量中最大计数的优化方法

车峻熙
2023-03-14

我想看看是否有一个有效的方法来比较计数(ACount,BCount,CCount,DCount,ECount),并评估JAVA中哪个计数最大?

该程序可以使用递归,但我想知道实现这一点的任何优化方法。

共有2个答案

童浩言
2023-03-14

你必须比较n个值,所以我认为不可能比O(n)做得更好。

“效率”取决于您的用例。如果你只有5个值,你只需要做一次,那么我认为启动一个流可能不是最好的方法。虽然它可能不是很重要,因为仅仅损失一次几毫秒通常不是什么大问题。但是,如果让JVM以10亿的值运行JIT(即时编译),那么检查不同的运行时是我首选的找出最“有效”的方法。

在下面的示例中,您可以使用不同的值运行它,以确定数组中有多少int,以及您希望运行max函数的次数。正如我提到的,当我只有5个值时,我发现流不是很有效。

您可能不应该在工作站上运行测试,因为这些工作站还有很多其他需要做的事情。我发现自己在尝试计时时非常不可预测,虽然它似乎始终为justLoop方法提供最佳输出。

C:\..snip..>java Testing.java
Ternary    : 23561
JustLoop   : 12663
MathMax    : 35049
Stream     : 46596

该代码只有4种不同的方法可以获得最大值:

  • 使用一个三元数,它将在每个循环中写入最大值
  • 一个常规的for循环和一个if语句
  • 使用Math.max()代替if语句。
  • 使用IntStream和它的max()函数。

它首先创建一个int数组。然后调用一个计时器函数,传入4种不同方法中的一种:

import java.util.stream.IntStream;

public class Testing {
  public static void main(String args[]){
    int repeat = 10000;
    int arraySize = 10000;
    int[] countsRandom = randomCounts(arraySize);
    printIt("Ternary",  timeIt(() -> regularLoopTernary(countsRandom), repeat));
    printIt("JustLoop", timeIt(() -> justLoop(countsRandom), repeat));
    printIt("MathMax",  timeIt(() -> justLoopWithMathMax(countsRandom), repeat));
    printIt("Stream",   timeIt(() -> stream(countsRandom), repeat));
  }
  
  public static int regularLoopTernary(int[] counts) {
    int max = Integer.MIN_VALUE;
    for (int i : counts) {
      max = i > max ? i : max;
    }
    return max;
  }

  public static int justLoop(int[] counts) {
    int max = Integer.MIN_VALUE;
    for (int i : counts) {
      if (i > max) {
        max = i;
      }
    }
    return max;
  }

  public static int justLoopWithMathMax(int[] counts) {
    int max = Integer.MIN_VALUE;
    for (int i : counts) {
      max = Math.max(max, i);
    }
    return max;
  }

  public static int stream(int[] counts) {
    return IntStream.of(counts)
                    .max()
                    .orElseThrow();
  }

  // get some ints
  public static int[] randomCounts(int amount) {
    return IntStream.range(0, amount)
                    .map(i -> (int) (Math.random() * Integer.MAX_VALUE))
                    .toArray();
  }

  // get the averge time only
  public static long timeIt(Runnable runMe, int times) {
    long start = System.nanoTime();
    for (int i = 0; i < times; i++) {
      runMe.run();
    }
    return (System.nanoTime() - start) / times;
  }

  public static void printIt(String title, long averagetime) {
    System.out.printf("%-10s : %d%n", title, averagetime);
  }
}
燕野
2023-03-14

有很多方法可以做到这一点,这取决于你觉得哪个更容易阅读。您可以首先使用IntStream:

int max = IntStream.of(343,434,61,1,512,5234,613434,561).max().getAsInt();

或者,您可以使用整数数组手动遍历每个值:

int[] list = {ACount, BCount, CCount, DCount, ECount};
int max = Integer.MIN_VALUE;
for (int i : list) {
    if (i > max) max = i;
}

或者对列表进行排序并获取最大值。如果还必须访问最小的值,这可能会更好。

int[] list = {ACount, BCount, CCount, DCount, ECount};
Arrays.sort(list);
int max = list[list.length - 1];

或者,您可以使用嵌套的数学max方法:

int max = Math.max(Math.max(Math.max(ACount, BCount), CCount), Math.max(DCount, ECount));

然而,重要的是要注意计算机的速度足够快,不需要每一个小的优化。无论您如何做,比较5个int值这样小的事情都不会花费很长时间,因此在这些情况下,通常最好让代码更具可读性,而不是更高效,因为可读性的降低往往不值得获得微小的收益。

 类似资料:
  • 这是我的作业: 编写一个程序来读取非负整数列表,并显示最大整数、最小整数和所有整数的平均值。用户通过输入不用于查找最大值、最小值和平均值的负前哨值来指示输入结束。平均值应为类型的值,因此将使用分数部分进行计算。 我得到了不同的部分来使用不同的方法:方法A使最大值和最小值正确,求和错误,方法B使求和和最大值正确,最小值错误。以下代码演示了方法B。一些变量被注释掉: 当我运行这个测试时,最大值、总和、

  • 问题内容: 我有3张桌子,每个国家和地区都有它的代币 还有这些国家中所有湖泊和所有山峰中的一个的表。 我现在必须说明山峰少于湖泊的国家。我现在尝试了几个小时,但找不到解决此问题的方法。我试图将3个表连接在一起- 但我不知道下一步该怎么做。我确定我必须使用嵌套的SQL命令。 这是我对每个国家的湖泊和山脉计数的尝试 但是以某种方式,两个列的count(Geo_lake.country)和count(G

  • 很抱歉,如果以前有人问过这个问题,但我非常不确定如何制定我的搜索以获得任何相关结果。 基本上,我有一个类“Wheel”,在该类中,我声明==操作符应该如何工作: 除非车轮的半径和转速与其他车轮相同,否则此操作有效,除非已切换。因此,换句话说,对于以下情况,它不会返回true: 2*PI*3*10 vs 2*PI*10*3 即使我把它打印出来,并且它们在控制台中是完全一样的(除非我的基本数学知识完全

  • 问题内容: 我正在寻找一种方法来计算等于组的最小或最大项目数。我每隔几天收到一次商品,每两周输入一次。我需要查看每个EntryDate的最小值和最大值ReceivedDate,以及最小值和最大值处的项目计数。在MS Access中使用SQL。 输入 当前查询 电流输出 期望的输出 问题答案: 我不知道MS Access是否允许这样的子查询。如果这不起作用,请让我知道,我将删除答案。否则:

  • 用数组和for循环 有溪流 一般来说,我知道ArrayList有开销,这可能导致数组的最小大小在看到增益之前。此外,如果有更好的方法来执行流操作或迭代。不确定forEach在这种情况下是否有效,因为它是一个终端操作,我需要按照array/arrayList的原始顺序捕获结果。

  • 我正在尝试欧拉项目的问题3,我的算法太慢了。有人知道如何优化它吗?我试图计算的数字是600851475143L。计算这个需要很长时间,所以我需要一种方法来加快计算速度。 逻辑: > 把从3到1的所有数字通读一遍 对于这些数字中的每一个,通过将它们除以中间的所有数字来检查它们是否为素数,如果它们不除以任何一个,则它们为素数 如果为素数,则将其添加到数组中。 **********更新*********