简体   繁体   中英

Finding the median value of an array?

I was wondering if it was possible to find the median value of an array? For example, suppose I have an array of size nine. Would it possible to find the middle slot of this array?

Assuming the array x is sorted and is of length n :

If n is odd then the median is x[(n-1)/2].
If n is even than the median is ( x[n/2] + x[(n/2)-1] ) / 2.

If you want to use any external library here isApache commons math library using you can calculate the Median .
For more methods and use take look at the API documentation

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

Calculate in program

Generally, median is calculated using the following two formulas given here

If n is odd then Median (M) = value of ((n + 1)/2)th item term.
If n is even then Median (M) = value of [((n)/2)th item term + ((n)/2 + 1)th item term ]/2

It is very easy as you have 9 elements (odd number).
Find the middle element of an array.
In your program you can declare array

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

then you need to sort array using Arrays#sort

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;

In java :

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

or

yourArray[yourArray.length/2];

in one line.

That's possible because in java arrays have a fixed size.

Note : 3/2 == 1


Resources :

In C++, you can use std::nth_element ; see 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];

Do it in one line like a pro:

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

cast to a double if you're expecting a double , etc.

The Java answer above only works if there are is an odd ammount of numbers here is the answer I got to the solution:

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];);
}

And note that this is a proof of concept and off the fly. If you think that you can make it more compact or less intensive, go right ahead. Please don't criticize it.

There is another alternative - in general, the suggestions here either suggest sorting the array then taking the median from such an array or relying on a (external) library solution. Fastest sorting algorithms today are linearithmic, on average, but it is possible to do better than that for the purposes of median calculation.

The quickest algorithm to compute median from an unsorted array is QuickSelect , which, on average, finds the median in time proportional to O(N). The algorithm takes array as argument, together with int value k (the order statistic, ie k-th smallest element in the array). The value of k , in this case, is simply N/2, where N is array length.

Implementation is little tricky to get right but here is an example which relies on Comparable<T> interface and Collections.shuffle() without any external dependencies.

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;
    }
}

The code produces the following order statistics for these input arrays:

            "                  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)]           " //

In the case of Java, dividing by 2.0 is enough to cast int to double :

 return n%2 == 0 ? (all[n/2] + all[n/2-1])/2.0 : all[(n-1)/2];

The first condition checks if the value is even.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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