【问题标题】:Why does this method not properly sort the arrays for larger numbers?为什么这种方法不能正确地对更大数字的数组进行排序?
【发布时间】:2019-08-21 11:13:34
【问题描述】:

我是 Java 新手,目前正在学习排序算法。我正在制作自己的合并排序算法,但在这样做时遇到了一个奇怪的问题。我在下面添加了我的 mergeArrays 方法(应该合并和排序两个排序数组)的代码,问题是它适用于较小的数字,例如{9, 13, 89, 199} 和 {1, 89, 127},但它不适用于更大的,例如{9, 13, 89, 5000} 和 {1, 89, 5001},因为它最终重复第二大数字,即它输出 {1, 9, 13, 89, 5000, 5000} 而不是 {1, 9, 13、89、5000、5001}。我只是不明白为什么会这样,如果有人能提供帮助,我将不胜感激!

谢谢!

import java.util.*;

public class MergeSortExample
{
  public Integer[] mergeArrays (Integer[] nums1, Integer[] nums2)
  {
    Integer[] nums = new Integer[nums1.length + nums2.length];

    int nums1First = 0, nums2First = 0;
    for (int i = 0; i < nums.length; i++)
    {
      nums[i] = Math.min (nums1[nums1First], nums2[nums2First]);
      if (nums[i] == nums1[nums1First])
      {
        if (nums1First == nums1.length - 1)
        {
          nums1[nums1First] = Integer.MAX_VALUE;
        }
        else
        {
          nums1First++;
        }
      }
      else if (nums[i] == nums2[nums2First])
      {
        if (nums2First == nums2.length - 1)
        {
          nums2[nums2First] = Integer.MAX_VALUE;
        }
        else
        {
          nums2First++;
        }
      }
    }
    return nums;
  }

  public static void main (String[] args)
  {
    /*Integer[] num1 = {9, 13, 89, 5000};
      Integer[] num2 = {1, 89, 5001}; does not work*/

    Integer[] num1 = {9, 13, 89, 199}; //works
    Integer[] num2 = {1, 89, 127}; //works

    MergeSortExample m = new MergeSortExample ();
    Integer[] testMerge = m.mergeArrays (num1, num2);

    for (int i = 0; i < testMerge.length - 1; i++)
    {
      System.out.print (testMerge[i] + ", ");
    }
    System.out.println (testMerge[testMerge.length - 1]);   
  }
}    

【问题讨论】:

  • “它不起作用”是什么意思?请edit你的问题说明你期待什么,为什么期待它,你正在观察什么,以及为什么它是错误的。
  • @Joe C 抱歉,刚刚编辑!
  • 将每个Integer 更改为intInteger.MAX_VALUE 除外),它将起作用

标签: java sorting


【解决方案1】:

Integer 表示有一个对象。在将对象与== 进行比较时,它们通常不等价,请考虑与String-s 的常见错误。
它适用于小数字的原因是它们被缓存了,有一个用于小整数的预实例化集合,描述于valueOf(int i)

public static Integer valueOf(int i)

返回代表指定int 值的Integer 实例。如果不需要新的Integer 实例,则通常应优先使用此方法而不是构造函数Integer(int),因为此方法可能会通过缓存频繁请求的值来显着提高空间和时间性能。此方法将始终缓存 -128 到 127(含)范围内的值,并可能缓存此范围之外的其他值。

当 Java 将 int-s 自动装箱到 Integer-s 时,可以假设使用此方法。

解决方案:不要那样做,使用int 数组。然后它会突然起作用。

您可以尝试的简单测试代码:

Integer a127=127;
Integer b127=127;
Integer a5000=5000;
Integer b5000=5000;
System.out.println(a127+"=="+b127+"? "+(a127==b127));
System.out.println(a5000+"=="+b5000+"? "+(a5000==b5000));

(在 Ideone 上查看它的实际操作:https://ideone.com/vEry18


旁注:虽然对称性很好,但我真的会考虑使用&lt;(或&gt;)而不是Math.min() 魔法,即使它会导致两次写入nums[i] =

if (nums1[nums1First] < nums2[nums2First])
{
  nums[i] = nums1[nums1First];
  if (nums1First == nums1.length - 1)
  {
    nums1[nums1First] = Integer.MAX_VALUE;
  }
  else
  {
    nums1First++;
  }
}
else
{
  nums[i] = nums2[nums2First];
  if (nums2First == nums2.length - 1)
  {
    nums2[nums2First] = Integer.MAX_VALUE;
  }
  else
  {
    nums2First++;
  }
}

【讨论】:

  • (或在对象上使用equals 而不是==
  • 感谢您的帮助!对于其余的代码,我需要使用 Integer 而不是 int,但是将 == 更改为 equals 就可以了。
【解决方案2】:

== 在 Integer 对象上导致问题。找到修改后的代码。

public class MergeSortExample {
    public Integer[] mergeArrays(Integer[] nums1, Integer[] nums2) {
        Integer[] nums = new Integer[nums1.length + nums2.length];

        int nums1First = 0, nums2First = 0;
        for (int i = 0; i < nums.length; i++) {
            if (nums1First >= nums1.length) {
                nums[i] = nums2[nums2First];
                nums2First++;
            } else if (nums2First >= nums2.length) {
                nums[i] = nums1[nums1First];
                nums1First++;
            } else {
                nums[i] = Math.min(nums1[nums1First], nums2[nums2First]);

                if (nums[i].equals (nums1[nums1First])) {
                    nums1First++;
                } else {
                    nums2First++;
                }
            }

        }
        return nums;
    }

    public static void main(String[] args) {
        Integer[] num1 = { 9, 13, 89, 5000 };
        Integer[] num2 = { 1, 89, 5001 };
        /* does not work */

        // Integer[] num1 = {9, 13, 89, 199}; //works
        // Integer[] num2 = {1, 89, 127}; //works

        MergeSortExample m = new MergeSortExample();
        Integer[] testMerge = m.mergeArrays(num1, num2);

        for (int i = 0; i < testMerge.length; i++) {
            System.out.print(testMerge[i] + ", ");
        }
    }
}

输出:

【讨论】:

  • 谢谢,我的代码终于可以运行了!我不敢相信我是如何使用 == 而不是 equals 的,这太愚蠢了,哈哈!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-22
  • 1970-01-01
  • 2015-12-27
相关资源
最近更新 更多