【问题标题】:The highest even number in a array数组中最大的偶数
【发布时间】:2018-03-14 11:47:13
【问题描述】:

我想要数组中最大的偶数

public static void main(String[] args) {
    int[] a = new int[]{10, 46, 78, 32, 3, 80, 92, 11, 39, 57};
    System.out.println(Arrays.toString(a));

    int largest = Integer.MAX_VALUE;
    for(int number : a) {
        if(number > largest) {
            largest = number;
        }
    }
    System.out.println(largest);
}

输出是:

[10, 46, 78, 32, 3, 80, 92, 11, 39, 57]
2147483647

【问题讨论】:

  • 替换 int largest = Integer.MAX_VALUE; 为 int largest = Integer.MIN_VALUE;
  • doc 勾选这个函数Collections.max()
  • 怎么样? ……
  • @CatarinaMota Java Doc.
  • 请注意,OP 想要最大的 偶数 数(不允许奇数)。

标签: java arrays max


【解决方案1】:

不要将largest 初始化为最大整数:

int largest = Integer.MAX_VALUE;

改为将其设置为 min int

int largest = Integer.MIN_VALUE;

或者,正如@Stultuske 建议的那样,初始化为数组中的第一个值:

int largest = a[0];

正如@Zabusa 指出的那样,你想要偶数。所以改进 if 语句,让它只在偶数上触发:

if (number > largest && number % 2 == 0) {

【讨论】:

  • 更好的是,到数组的第一个元素。
  • @CatarinaMota 不,不是。
  • @CatarinaMota 您需要使用最差的最大值作为初始猜测。否则你的元素总是会更小,因此你最初的猜测是最大的元素。这就是为什么我们首先猜测MIN_VALUE 是最大元素。由于数组的元素只能变得更大。只需在纸上为{1, 2} 之类的小示例播放算法,您就会明白为什么这样做是有意义的。
  • @Stefan 请注意,OP 实际上想要“最高偶数数”。您的答案(如果用于 OPs 算法)只能找到最大的数字,可能是奇数。
  • 请注意,使用第一个元素作为初始猜测现在通常不再起作用。因为如果该元素是奇数,则输出将是该元素以防所有元素都是奇数。对于maxEven 不存在的情况,也许像-1 这样的东西会是一个更好的指标。
【解决方案2】:

说明

您的代码有两个问题。第一个是,正如其他人已经指出的那样,您以Integer.MAX_VALUE 作为初始猜测,这是错误的逻辑。

您需要使用可能的最差最大值作为初始猜测。否则你的元素总是会更小,因此你最初的猜测是最大的元素。这就是为什么我们首先猜测MIN_VALUE 作为最大元素。由于数组的元素只能变得更大。只需在纸上播放一个像 {1, 2} 这样的小例子的算法,你就会明白为什么这样做是有意义的。

第二个问题是您实际上正在考虑所有值,但您只想考虑偶数值。我们通过跳过所有奇数值轻松解决这个问题。


代码

这是您的代码,其中包含两个修复:

public static void main(String[] args) {
    int[] a = new int[]{10, 46, 78, 32, 3, 80, 92, 11, 39, 57};
    System.out.println(Arrays.toString(a));

    // Start with lowest value as initial guess
    int largest = Integer.MIN_VALUE;
    for (int number : a) {
        // Skip number if odd
        if (number % 2 == 1) {
            continue;
        }

        // Now we only consider and collect even numbers
        if (number > largest) {
            // Update the current guess
            largest = number;
        }
    }
    // We now considered all elements, the guess is
    // final and correct.
    // And also even since we skipped odd values.
    System.out.println(largest);
}

注意事项

如果数组不包含任何偶数,则输出将为Integer.MIN_VALUE,您可以考虑这种特殊情况并使用一些if 子句来捕获它。

其他人建议使用数组的一个元素作为初始猜测。由于您只需要偶数值,因此您可能只考虑使用数组的 偶数值 进行初始猜测。否则,如果数组不包含偶数,则再次输出奇数。

您可以使用通用且紧凑的Stream 解决方案来替代自定义方法:

int maxEven = Arrays.stream(a)
    .filter(a -> a % 2 == 0) // Only even values
    .max()  // OptionalInt
    .orElse(-1); // Gets the value or uses -1 if not present

【讨论】:

    【解决方案3】:

    使用 Streams 的替代且简单的解决方案:

    int[] a = new int[] { 10, 46, 78, 32, 3, 80, 92, 11, 39, 57 };
    System.out.println(Arrays.toString(a));
    
    int largest = Arrays.stream(a).filter((i) -> i % 2 == 0).max().getAsInt();
    
    
    System.out.println(largest);
    

    一种高效快捷的方法。如果列表中没有偶数,getAsInt() 将抛出一个 NoSuchElementException,它可以很容易地被捕获并以您喜欢的任何方式处理。

    如果您不想处理异常但希望有一个已定义的值表明您的输入可能格式不正确,那么您也可以使用orElse(-1) 或类似名称来代替getAsInt()

    【讨论】:

    • 我喜欢Stream 解决方案,但在处理Optional 对象时请考虑使用其他方法,例如.orElse(-1)get 方法通常不受欢迎,设计人员甚至考虑过弃用它们。
    • 虽然我大体上同意你的观点,但如果 Optional 不存在,我确实使用 getAsInt() 来完全按照它的工作方式使用 NoSuchElementException。如果您愿意,显然也可以使用orElse。我会编辑它。
    • 是的,但如果您不立即捕获异常,那将是一个坏习惯。既然你仍然有一个RuntimeException,如果项目测试阶段没有分支命中它,它可能永远不会被发现。然后您在项目中发现了一个未发现的错误,该错误可能会在发布后使​​应用程序崩溃。这违背了Optional 的目的,您可以将nullNullPointerException 一起使用。这就是为什么他们不鼓励使用get,而是建议始终尝试其他方法之一。因为否则Optional 与旧方法相比不会提供任何好处。
    • 我当然知道你来自哪里并同意你的看法。对于这个最小的例子,这样做完全没问题,但鼓励坏习惯可能不是一件好事。
    • 是的,这里很好。只是想留下它作为注释:)
    【解决方案4】:

    如果您可以访问 Java 8 及更高版本,我肯定会查看 Streams API。您可以将整数数组视为值流。使用该流,您可以访问高级函数,例如 min、max 和 filter。在 Java 中使用 Streams 有很多优点,如下所述。

    Java 8 Streams 可以看作是延迟构造的集合,其中的值是在用户需要时计算的。实际集合的行为与它完全相反,它们是一组急切计算的值(无论用户是否需要特定值)。

    您可以继续阅读here

    所以,要回答您最初关于如何在数组中检索最高值的问题,您可以这样做:

    // 只计算最大值的sn-p

    int maxValue = Arrays.stream(arrayOfVals)
      .mapToInt(v -> v)
      .filter(val -> val%2 == 0)
      .max()
      .orElse(-1);
    

    【讨论】:

    • 我喜欢Stream 解决方案,但在处理Optional 对象时请考虑使用其他方法,例如.orElse(-1)get 方法通常不被鼓励,设计者甚至考虑过弃用它们。另请注意,OP 只想收集 偶数 个数字。
    【解决方案5】:

    对正数和负数都有效偶数

        int[] a = new int[]{100, 45, 77, 33, 3, 81, 80, 8, 120, 100,-2};
        int maxvalue = Integer.MIN_VALUE;
        for (int anA : a) {
            if (anA % 2 == 0) {
                if (anA >= maxvalue)
                    maxvalue = anA;
            }
        }
    

    【讨论】:

    • 如果列表是int[] a = new int[] {-10, -2};呢?
    • Ben 想说的是,您最初对maxValue = 0 的猜测可能比数组中所有偶数元素都大。在这种情况下,输出将是错误的,并显示0 而不是-2{-10, -2}。所以你需要调整你的初始猜测,它必须是<= 最低可能的maxEven 结果,否则将找不到maxEven
    • thnx @Zabuza 你的评论帮助我:) 理解问题
    • Mh. -2 仅适用于此特殊输入。如果我使用{-10, -8} 尝试您的代码,它将产生-2 而不是-8。唯一的可能性是要么从数组中提取一个偶数,要么只使用 Java Integer.MIN_VALUE 中可能的最低数字。在任何情况下,您都需要额外处理 maxEven 不存在的特殊情况,因为没有像 {1, 3} 这样的偶数。
    • @Zabuza 我需要一个关于我写的代码是好是坏的建议,因为我是学生并且仍在学习编写更好的代码
    【解决方案6】:

    试试这个代码:

    public static void main (String [] args)
      {
        int [] arr = {31,-2,3,-4,9,3,8,11,7};
        int maxEven, firstEven = 1;
        for (int i = 0; i < arr.length; i++)
           if(arr [i]%2 == 0)
            {
                firstEven = arr [i];
                break;
            }
        maxEven = firstEven;
        for (int j = 0; j < arr.length; j++)
            if (arr [j]%2 == 0 && arr [j]>maxEven)
               maxEven = arr [j];
        if (maxEven == 1)
           System.out.println ("No even numbers in this array!");
        else
           System.out.println ("The maximum even number is: "+maxEven);
      }
    

    【讨论】:

    • 考虑添加一个解释,说明您为什么认为这是一个更好的解决方案
    【解决方案7】:

    我通过使用三元运算符尝试了一种不同的方法来解决这个问题。
    虽然我知道,嵌套三元运算符不利于性能。我们也可以在那里使用简单的 If/Else 条件。
    一个小实验永远不会受到伤害。永远不要停止学习生活中的新事物。

    我的工作代码:

    public static void main(String[] args) {
        int[] numArray = {1, 121, 9, -1024, -30001, 5, 41, 181, 91};
        System.out.println("Max Even No is :: "+getMaxEvenNum(numArray));
    }
    
    public static int getMaxEvenNum(int[] numArray) {
        int maxNo = Integer.MIN_VALUE;
        for(int i=0; i< numArray.length; i++) {
            for(int j=i+1; j< numArray.length; j++) {
                int maxOf2 = numArray[i]>numArray[j] ? (numArray[i]%2 == 0 ? numArray[i] : maxNo) : (numArray[j]%2 == 0 ? numArray[j] : maxNo);
                maxNo = maxNo>maxOf2 ? maxNo : maxOf2;
            }
        }
        return maxNo;
    }
    

    它将给出以下输出:

    Max Even No is :: -1024
    

    如果不存在偶数,则给出最小整数值。

    【讨论】:

      【解决方案8】:

      最简单的方法(如果您确实使用如此小的数组)有: 步骤 1. 对数组进行排序 步骤 2. 打印最后一个元素。

      对于更大的阵列,Stefan 提供的方案确实是更好的选择。

      【讨论】:

      • 那将是 O(n log n)
      • 也许很简单。但可能非常昂贵。问题中的循环是 O(n),没有排序算法可以匹配。
      • 因为问题是关于手头的数组(包含 10 个元素),所以“费用”是最小的。
      • 你是对的。但是,如果您在答案中包含此类注释会更好。否则,尤其是初学者,可能总的来说认为这是一个聪明的想法,但事实并非如此。已经说过,maxTheta(n) 中,而基于比较的排序Theta(n log n) 中。
      • @Stultuske 请注意,OP 实际上想要“最高偶数数”。您的答案(如果用于 OPs 算法)只能找到最大的数字,可能是奇数。
      猜你喜欢
      • 2020-05-13
      • 2021-03-10
      • 2015-08-22
      • 2012-06-06
      • 2022-10-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-15
      相关资源
      最近更新 更多