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 mi开发者_开发技巧ddle 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 is Apache 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;
}
.......
- For more on evaluate method AbstractUnivariateStatistic#evaluate
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 C++, you can use std::nth_element
; see http://cplusplus.com/reference/algorithm/nth_element/.
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 :
- Java tutorial - Arrays
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, i.e. 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.
精彩评论