найти второй и третий максимальный массив элементов java

Мне нужно найти 1-й, 2-й и 3-й по величине массив. Я знаю, что могу просто отсортировать его и вернуть массив [0], массив [1], массив [3]. Но проблема в том, что мне нужен индекс, а не значение. Например, если у меня есть float[] listx={8.0, 3.0, 4.0, 5.0, 9.0}, он должен вернуть 4, 0 и 3.

Вот код, который у меня есть, но он не работает:

//declaration max1-3        
public void maxar (float[] listx){

    float maxel1=0;
    float maxel2=0;
    float maxel3=0;

    for (int i=0; i<listx.length; i++){
        if(maxel1<listx[i])
        {maxel1=listx[i];
        max1=i;
        }
    }
    listx[max1]=0; //to exclude this one in nextsearch

    for (int j=0; j<listx.length; j++){
        if(listx[j]>maxel2)
        {maxel2=listx[j];
        max2=j;
        }
    }
    listx[max2]=0;

    for (int k=0; k<listx.length; k++){
        if(listx[k]>maxel3)
        {maxel3=listx[k];
        max3=k;
        }
    }
}

Я получаю max1 правильно, но после этого все элементы превращаются в 0. Следовательно, max2 и max3 становятся 0. Пожалуйста, предложите мне, что не так с этим решением. Спасибо.


person username10    schedule 01.12.2012    source источник
comment
Проверьте этот пост.   -  person Extreme Coders    schedule 01.12.2012


Ответы (5)


Вы можете найти три элемента, используя один цикл, и вам не нужно изменять массив.

Когда вы сталкиваетесь с новым самым большим элементом, вам нужно сдвинуть предыдущий самый большой и предыдущий второй по величине вниз на одну позицию.

Точно так же, когда вы найдете новый второй по величине элемент, вам нужно сдвинуть maxel2 на maxel3.

Вместо использования трех переменных вы можете использовать массив. Это позволит упростить логику и упростить обобщение до k самых больших элементов.

person NPE    schedule 01.12.2012

Сделать 3 прохода по массиву: при первом проходе найти значение и 1-й индекс максимального элемента M1, при втором проходе найти значение и 1-й индекс максимального элемента M2, который меньше M1, и при третьем проходе найти значение/1-й индекс M3 < M2.

person Victor Sorokin    schedule 01.12.2012
comment
3 прохода это перебор. Необходим только один проход. - person Victor Zamanian; 01.12.2012

Попробуйте этот код, он будет работать :)

  public class Array
    {
  public void getMax( double ar[] )
   {
    double max1 = ar[0]; // Assume the first
    double max2 = ar[0]; // element in the array
    double max3 = ar[0]; // is the maximum element.
    int ZERO = 0; 
     // Variable to store inside it the index of the max value to set it to zero.

    for( int i = 0; i < ar.length; i++ )
    {
        if( ar[i] >= max1)
        {
            max1 = ar[i];
            ZERO = i;
        }
    }

    ar[ZERO] = 0; // Set the index contains the 1st max to ZERO.

    for( int j = 0; j < ar.length; j++ )
    {
        if( ar[j] >= max2 )
        {
            max2 = ar[j];
            ZERO = j;
        }
    }

    ar[ZERO] = 0; // Set the index contains the 2st max to ZERO.

    for( int k = 0; k < ar.length; k++ )
    {
        if( ar[k] >= max3 )
        {
            max3 = ar[k];
            ZERO = k;
        }
    }

            System.out.println("1st max:" + max1 + ", 2nd: " +max2 + ",3rd: "+ max3);                              
   }

public static void main(String[] args)
{
    // Creating an object from the class Array to be able to use its methods.
    Array array = new Array();
    // Creating an array of type double.
    double a[] = {2.2, 3.4, 5.5, 5.5, 6.6, 5.6};

    array.getMax( a ); // Calling the method that'll find the 1st max, 2nd max, and      and 3rd max.
}

  }
person Community    schedule 01.12.2012

Я предлагаю сделать один проход вместо трех для оптимизации. Код ниже работает для меня. Обратите внимание, что код не утверждает, что listx имеет как минимум 3 элемента. Вам решать, что должно произойти, если он содержит только 2 элемента или меньше.

Что мне нравится в этом коде, так это то, что он выполняет только один проход по массиву, что в лучшем случае будет иметь более быстрое время выполнения по сравнению с выполнением трех проходов с коэффициентом, пропорциональным количеству элементов в listx.

Предположим, что i1, i2 и i3 хранят индексы трех наибольших элементов в listx, а i0 является одним из i1, i2 и i3, которые указывают на наименьший элемент. Вначале i1 = i2 = i3, потому что мы еще не нашли самые большие элементы. Итак, пусть i0 = i1. Если мы находим новый индекс j такой, что это listx[j] > listx[i0], мы устанавливаем i0 = j, заменяя этот старый индекс индексом, который ведет к большему элементу. Затем мы находим индекс среди i1, i2 и i3, который теперь ведет к наименьшему элементу из трех, так что мы можем безопасно отбросить эту > один на случай появления нового большого элемента.

Примечание. Этот код написан на C, поэтому переведите его на Java, если хотите его использовать. Я позаботился о том, чтобы использовать аналогичный синтаксис, чтобы упростить задачу. (Я написал его на C, потому что мне не хватало среды тестирования Java.)

void maxar(float listx[], int count) {
    int maxidx[3] = {0};

    /* The index of the 3rd greatest element
     * in listx.
     */
    int max_3rd = 0;

    for (int i = 0; i < count; i++) {
        if (listx[maxidx[max_3rd]] < listx[i]) {
            /* Exchange 3rd greatest element
             * with new greater element.
             */
            maxidx[max_3rd] = i;

            /* Find index of smallest maximum. */
            for (int j = (max_3rd + 1) % 3; j != max_3rd; j = (j + 1) % 3) {
                if (listx[maxidx[j]] < listx[maxidx[max_3rd]]) {
                    max_3rd = j;
                }
            }
        }
    }

    /* `maxidx' now contains the indices of
     * the 3 greatest values in `listx'.
     */

    printf("3 maximum elements (unordered):\n");
    for (int i = 0; i < 3; i++) {
        printf("index: %2d, element: %f\n", maxidx[i], listx[maxidx[i]]);
    }
}
person Victor Zamanian    schedule 01.12.2012

person    schedule
comment
Пожалуйста, добавьте описание решения, которое вы предлагаете. - person il_raffa; 05.12.2015