Поиск медианного значения массива?

Мне было интересно, можно ли найти медианное значение массива? Например, предположим, что у меня есть массив девятого размера. Можно ли найти средний слот этого массива?

8 ответов


предполагая, что массив x сортируется и имеет длину n:

Если n нечетно, то медиана равна x [(n-1)/2].
Если n четное, чем медиана (x[n / 2] + x[(n/2)-1]) / 2.


Если вы хотите использовать любые внешние библиотеки Apache commons math library используя Вы можете рассчитать в среднем.
Для получения дополнительных методов и использования посмотрите на документация по API

import org.apache.commons.math3.*;
.....
......
........
//calculate median
public double getMedian(double[] values){
 Median median = new Median();
 double medianValue = median.evaluate(values);
 return medianValue;
}
.......

рассчитать в программе

как правило, медиана рассчитывается с использованием следующего две формулы приведенный здесь

Если N нечетно, то медиана (M) = значение ((n + 1)/2) - го элемента.
Если n даже тогда медиана (M) = значение [((n)/2) - го термина элемента + ((n)/2 + 1) - го термина элемента ]/2

Это очень просто, так как у вас есть 9 элементов (нечетное число).
Найдите средний элемент массива.
В вашей программе вы можете объявить array

//as you mentioned in question, you have array with 9 elements
int[] numArray = new int[9]; 

затем нужно отсортировать массив, используя массивы#вроде

Arrays.sort(numArray);
int middle = numArray.length/2;
int medianValue = 0; //declare variable 
if (numArray.length%2 == 1) 
    medianValue = numArray[middle];
else
   medianValue = (numArray[middle-1] + numArray[middle]) / 2;

в java:

int middleSlot = youArray.length/2;
yourArray[middleSlot];

или

yourArray[yourArray.length/2];

в одну строку.

это возможно потому, что в Java массивы имеют фиксированный размер.

Примечание : 3/2 == 1


ресурсы :


В C++, вы можете использовать std::nth_element; см. http://cplusplus.com/reference/algorithm/nth_element/.


vector<int> v;
size_t len = v.size;
nth_element( v.begin(), v.begin()+len/2,v.end() );

int median = v[len/2];

ответ Java выше работает только в том случае, если есть нечетное количество чисел, вот ответ, который я получил к решению:

if (yourArray.length % 2 == 0){

     //this is for if your array has an even ammount of numbers
     double middleNumOne = yourArray[yourArray.length / 2 - 0.5]
     double middleNumTwo = yourArray[yourArray.length / 2 + 0.5]
     double median = (middleNumOne + middleNumTwo) / 2;
     System.out.print(median);

}else{

     //this is for if your array has an odd ammount of numbers
     System.out.print(yourArray[yourArray.length/2];);
}

и обратите внимание, что это доказательство концепции и от мухи. Если вы думаете, что можете сделать его более компактным или менее интенсивным, продолжайте. Пожалуйста, не критикуйте его.


есть еще одна альтернатива-в общем, предложения здесь либо предлагают отсортировать массив, а затем взять медиану из такого массива, либо полагаться на (внешнее) библиотечное решение. Самые быстрые алгоритмы сортировки сегодня являются линеарифмическими, в среднем, но можно сделать лучше, чем для целей расчета медианы.

самый быстрый алгоритм для вычисления медианы из несортированного массива -QuickSelect, который, в среднем, находит медиану времени пропорционально O (N). Алгоритм принимает массив в качестве аргумента вместе с int value k (статистика порядка, т. е. k-й наименьший элемент в массиве). Значение k, в этом случае просто N / 2, где N-длина массива.

реализация немного сложно получить право, но вот пример, который опирается на Comparable<T> интерфейс и Collections.shuffle() без каких-либо внешних зависимостей.

public final class QuickSelectExample {

    public static <T extends Comparable<? super T>> T select(T[] a, int k) {
        if (k < 1) throw new IllegalStateException("Invalid k - must be in [1, inputLength].");
        if (k > a.length) throw new IllegalStateException("K-th element exceeds array length.");
        Collections.shuffle(Arrays.asList(a));
        return find(a, 0, a.length - 1, k - 1);
    }

    private static <T extends Comparable<? super T>> T find(T[] a, int lo, int hi, int k) {
        int mid = partition(a, lo, hi);

        if (k == mid) return a[k];
        else if (k < mid) return find(a, lo, mid - 1, k); // search left subarray
        else if (k > mid) return find(a, mid + 1, hi, k); // search right subarray
        else throw new IllegalStateException("Not found");
    }

    private static <T extends Comparable<? super T>> int partition(T[] a, int lo, int hi) {
        T pivot = a[lo];
        int i = lo + 1;
        int j = hi;

        while (true) { // phase 1
            while (i <= hi && (less(a[i], pivot) || eq(a[i], pivot))) // is a[i] >= pivot?
                i++;

            while (j >= i && !less(a[j], pivot))  // is a[j] <= pivot?
                j--;

            if (i >= j) break;
            exch(a, i, j);
        }
        exch(a, lo, j); // phase 2
        return j;
    }

    private static <T extends Comparable<? super T>> boolean less(T x, T y) {
        return x.compareTo(y) < 0;
    }

    private static <T extends Comparable<? super T>> boolean eq(T x, T y) {
        return x.compareTo(y) == 0;
    }
}

код производит следующую статистику заказа для этих входных данных массивы:

            "                  Input Array                    |                                                           Actual Output [format: (index k -> array element)]                                                           ", //
            "                                                 |                                                                                                                                                                        ", //
            "       [S, O, R, T, E, X, A, M, P, L, E]         |                            [(1 -> A), (2 -> E), (3 -> E), (4 -> L), (5 -> M), (6 -> O), (7 -> P), (8 -> R), (9 -> S), (10 -> T), (11 -> X)]                            ", //
            "   [P, A, B, X, W, P, P, V, P, D, P, C, Y, Z]    |            [(1 -> A), (2 -> B), (3 -> C), (4 -> D), (5 -> P), (6 -> P), (7 -> P), (8 -> P), (9 -> P), (10 -> V), (11 -> W), (12 -> X), (13 -> Y), (14 -> Z)]           " //

сделайте это в одной строке, как профи:

return (arr[size/2] + arr[(size-1)/2]) / 2;

бросил в double Если вы ожидаете double, etc.