简体   繁体   English

用户提供的整数数组的第一,第二和第三大数

[英]First, Second and Third largest number from user provided integer array

In this program, size of array and array elements are taken from user. 在此程序中,数组和数组元素的大小取自用户。

This code passes all the cases I have tried but not able to pass, where size of array is 4 and elements are {5,5,5,2} 这段代码通过了我尝试过但无法通过的所有情况,其中数组的大小为4,元素为{5,5,5,2}

Here output should be 5 5 5 这里的输出应该是5 5 5
But I am getting 2 2 5 但是我得到2 2 5

I am able to figure out the problem is in this part. 我能够找出问题所在。

else if((max1 == max2 && max2 == max3 && max1 == max3) && x[i] < max2)
                {
                    max2 = x[i];
                    if(max2 < max3)
                    {
                        max3 = max2;
                    }
                }

How can I solve this problem using array only. 如何仅使用数组解决此问题。 Don't need solution in collections. 在集合中不需要解决方案。

import java.util.*;
    class ThirdLargest 
    {
        public static void main(String[] args) 
        {
            Scanner sc = new Scanner(System.in);
            System.out.println("Enter size for array: ");
            int size = sc.nextInt();
            int[] x = new int[size];
            for(int i = 0; i < x.length; i++)
            {
                System.out.println("Enter elements for array: ");
                x[i] = sc.nextInt();
            }
            System.out.println("Array is: ");
            for(int i = 0; i < x.length; i++)
            {
                System.out.print(x[i] +"    ");
            }
            System.out.println();
            if (x.length >= 3)
            {
                int max1 = x[0], max2 = x[0], max3 = x[0];
            for (int i = 1; i < x.length; i++)
            {
                    if(x[i] > max1)
                    {
                        max3 = max2;
                        max2 = max1;
                        max1 = x[i];
                    }
                    else if(x[i] > max2)
                    {
                        max3 = max2;
                        max2 = x[i];
                    }
                    else if (x[i] > max3)
                    {
                        max3 = x[i];
                    }
                    else if((max1 == max2 && max2 == max3 && max1 == max3) && x[i] < max2)
                    {
                        max2 = x[i];
                        if(max2 < max3)
                        {
                            max3 = max2;
                        }
                    }
                    else if(max2 == max3 && x[i] < max3)
                        {
                            max3 = x[i];
                        }
                }
            System.out.println("3rd, 2nd and 1st maximum: " + max3 +"   "+max2+"    "+max1);
            }
            else
            {
                System.out.println("Array size is short");      
            }       
        }
    }

This code is not human readable, you will stuck in this for hours trying to debug. 该代码不是人类可读的代码,您将在其中尝试调试几个小时。 First, you need to split this code to methods, don't try to do all thing in one method. 首先,您需要将此代码拆分为方法,不要尝试在一个方法中做所有事情。 You need to decouple logic of receiving int array from user from logic that doing max values calculation. 您需要从进行最大值计算的逻辑中分离出从用户接收int数组的逻辑。 Example: 例:

public int[] threeMaximumValuesFrom(int[] array) {
    int[] sorted = sortArray(array);
    int[] result = {
        sorted[array.length - 1];
        sorted[array.length - 2];
        sorted[array.length - 3];
    }
    return result;
}

private int[] sortArray(int[] array) {
    //when you don't want to use jdk sort implement your own
    //in any way other parts of code should knows nothing about it
    Arrays.sort(array);
    return array;
}

The problem is that repeated integers in the array are not kept track of as unique elements. 问题在于数组中重复的整数不能作为唯一元素来跟踪。

When you look at the array x = [5, 5, 5, 2] on paper you can see that there are three unique int elements of value 5 so the three largest should be 5, 5, 5 but the way the tests are now, when it reaches the value 2 at the end of the array, it doesn't know that max3 , max2 , and max1 each represent three distinct ints of value 5 for x[0] , x[1] , and x[2] . 当您在纸上查看数组x = [5, 5, 5, 2] ,可以看到存在三个唯一的 int元素,它们的值均为5所以三个最大的int元素应为5, 5, 5但是现在的测试方式,当它在数组末尾达到值2时,它不知道max3max2max1分别代表x[0]x[1]x[2]三个不同的 ints ,值5

The problem can be seen here in this code section: 在以下代码部分中可以看到问题:

...

else if ((max1 == max2 && max2 == max3 && max1 == max3) && x[i] < max2) {
    max2 = x[i];
    if (max2 < max3) {
        max3 = max2;
    }
} else if (max2 == max3 && x[i] < max3) {
    max3 = x[i];
}

...

It doesn't work for two reasons: 它不起作用有两个原因:

  1. In the first if/else block, both max2 and max3 are changed so the other if/else blocks will work during future loop iterations, but the problem is that this assumes there will be a next iteration . 在第一个if/else块中, max2max3都被更改,因此其他if/else块将在以后的循环迭代中工作,但是问题在于, 这假设将要进行下一个迭代 It does not work when the code block above is the last thing executed in the loop, eg [5, 5, 5, 2 ]. 如果上面的代码块是循环中最后执行的内容,例如[5, 5, 5, 2 5、5、5、2],则此功能不起作用。

    • (side note) if max1 , max2 , and max3 are all equal, and x[i] < max2 , then after the line: (旁注)如果max1max2max3都相等,并且x[i] < max2 ,则在该行之后:

       max2 = x[i]; 

      max2 will always be less than max3 so the test if (max2 < max3) { is not needed. max2始终小于max3因此max3测试if (max2 < max3) {

  2. The tests max1 == max2 && max2 == max3 && max1 == max3 and max2 == max3 do not handle the cases where: 测试max1 == max2 && max2 == max3 && max1 == max3max2 == max3无法处理以下情况:

    • max1 , max2 , and max3 are all equal, but each represents a different element in the array, eg [5, 5, 5, 2] , when i = 3 in the for loop then max1 could represent x[0] , max2 could represent x[1] , and max3 could represent x[2] but because uniques are not kept track of, max2 and max3 are reassigned to 2 and because this is the last thing the for loop executes, the output is 2, 2, 5 . max1max2max3都相等,但是每个代表数组中的一个不同元素,例如[5, 5, 5, 2] max3 [5, 5, 5, 2] ,如果在for循环中i = 3 ,则max1可以表示x[0]max2可以表示x[1]max3可以表示x[2]但因为不重复没有保持轨道,的max2max3被重新分配给2并且由于这是最后的事for循环执行,则输出为2, 2, 5

    • max2 and max3 are equal but each represents a different element in the array, eg for [7, 7, 8, 2] , when i = 3 in the for loop, max2 represents x[0] and max3 represents x[1] but again, because uniques are not kept track of, max3 is reassigned to 2 and the output is 2, 7, 8 instead of 7, 7, 8 . max2max3相等,但每个代表数组中的不同元素,例如[7, 7, 8, 2] max3 [7, 7, 8, 2] ,当for循环中i = 3时, max2代表x[0]max3代表x[1]但是再次,因为唯一身份没有保持轨道, max3重新分配到2 ,输出为2, 7, 8 ,而不是7, 7, 8

To be clear: 要清楚:

  • If you tested the array [5, 5, 5, 5, 2] where the 2 occurs at index 4 , the program would output 2, 2, 5 because of the reasons mentioned above. 如果所测试的阵列[5, 5, 5, 5, 2]其中2发生在索引4 ,该方案将输出2, 2, 5的因的原因如上所述。
  • If you tested the array [5, 5, 5, 2, 5] where the 2 occurs at index 3 , the program would output 2, 5, 5 because there is only one 5 that appears after the 2 . 如果测试数组2 [5, 5, 5, 2, 5] ,其中2出现在索引3 ,则程序将输出2, 5, 5因为在2之后仅出现5
  • If you tested the array [5, 5, 2, 5, 5] where the 2 occurs at index 2 , the program would output 5, 5, 5 because there are two 5s that occur after the 2 . 如果所测试的阵列[5, 5, 2, 5, 5]其中2发生在索引2 ,该方案将输出5, 5, 5因为有两个5s在之后发生的2 In the end: max1 , max2 , and max3 all equal each other, 5 . 最后: max1max2max3彼此相等, 5
  • If you tested the array [5, 5, 2, 5, 5, 3] which is just the previous array but with 3 added at the end, then the program would output 3, 3, 5 because when i = 5 in the for loop, max1 , max2 , and max3 all equal each other, 5 , and the program assumes this is because they were all initially set to x[0] . 如果您测试的数组[5, 5, 2, 5, 5, 3]只是前一个数组,但最后添加了3 ,则程序将输出3, 3, 5因为当for i = 5时环, max1max2 ,和max3所有彼此相等, 5 ,程序假定这是因为它们是所有初始设定为x[0]

Now that you understand why the program does not work, I believe a better way to solve this problem would be to first initialize max1 , max2 , and max3 to the lowest possible value using the Integer wrapper class, read about it here : 现在你明白为什么程序无法正常工作,我认为更好的方法来解决这个问题的方法是首先初始化max1max2max3使用可能的最低值Integer包装类,了解它在这里

Replace 更换

int max1 = x[0], max2 = x[0], max3 = x[0];

with

int max1, max2, max3;
max1 = max2 = max3 = Integer.MIN_VALUE;

then change the last for loop to begin at index 0 now instead of 1 然后将最后一个for循环更改为从索引0开始而不是1

for (int i = 0; i < x.length; i++) {

and delete the last two if/else blocks: 并删除最后两个if/else块:

else if ((max1 == max2 && max2 == max3 && max1 == max3) && x[i] < max2) {
    max2 = x[i];
    if (max2 < max3) {
        max3 = max2;
    }
} else if (max2 == max3 && x[i] < max3) {
    max3 = x[i];
}

You were very close to solving it and only a few small changes are needed to fix the bugs. 您已经非常接近解决它了,只需要进行一些小的更改就可以修复错误。

Hope this was helpful, and cheers! 希望这会有所帮助,并为之加油!

int[] numbers = {5, 5, 5, 2};
Arrays.stream(numbers).sorted().skip(numbers.length - 3).forEach(System.out::println);

We make stream out of your array, then we sort it, we skip arrayLength - n elements (n represents how many max numbers you want to print out) and we print each one of the numbers that are left. 我们从数组中取出流,然后对其进行排序,跳过arrayLength-n个元素(n表示要打印的最大数量),然后打印剩下的每个数字。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM