3
\$\begingroup\$

The method medianOfThree

  1. returns the median of the first, center and last element in array
  2. sorts the first, center, and last element of the array, so they are in order EXCEPT places the center in the second to last position.

Examples:

INPUT: 1,2,3
RETURN:2
EFFECT:1,2,3

INPUT: 3,2,1
RETURN:2
EFFECT:1,2,3

INPUT: 2,3,1
RETURN:2
EFFECT:1,2,3

INPUT: -2,-3,-8,1,20
RETURN:-2
EFFECT:-8,-3,1,-2,20

INPUT: 15,20,5,10
RETURN:15
EFFECT:10,5,15,20

NOTE: when the center is moved to the second to last position, it doesn't matter where the value that was previously there goes (as long as it's still in the array). Though this probably isn't relevant. In fact, as long as the first, last and one before last are in the correct place, the rest of the elements can get scrambled.

Here is the code. I tested it, but since it is rather complex it was hard to test (need to check return value and array and think carefully of expected result). Any suggestions for tools that make testing code like this easier?

/*
*Sorts first, center and last element, swaps the new center element with the one before the new last and returns its value.
*/
public static int medianOfThree(int[] sample, int start, int end) {
 if(sample.length < 3) {
 throw new IllegalArgumentException("arrays of length three or greater");
 }
 int center = (int)Math.floor((end-start)/2);
 if(sample[start] > sample[end])
 swap(sample, start, end);
 if(sample[start] > sample[center])
 swap(sample, start, center);
 if(sample[center] > sample[end])
 swap(sample, center, end);
int secondLast = end - 1
 swap(sample, center, secondLast );
 return sample[secondLast];
}
//swaps two elements in array given their positions
private static void swap(int[] sample, int x, int y) {
 int temp = sample[x];
 sample[x] = sample[y];
 sample[y] = temp;
}
mdfst13
22.4k6 gold badges34 silver badges70 bronze badges
asked Jul 1, 2016 at 11:55
\$\endgroup\$

2 Answers 2

2
\$\begingroup\$

Bug when finding center

Your code for finding the center is wrong:

int center = (int)Math.floor((end-start)/2);

For example, if start is 10 and end is 20, your calculation makes center be 5 when it should be 15. Also, you don't need Math.floor because you are using integer arithmetic so there is nothing to round up or down. You should change your code to this:

int center = start + (end-start)/2;
answered Jul 1, 2016 at 17:44
\$\endgroup\$
3
\$\begingroup\$

You seem to specify that it will only be 3 elements in the title of the question, but your input shows you input more than 3 every so often. Your sorting "algorithm" (a lot of swaps) is quite naïve in that sense - for examples of some sorting algorithms that you could implement, take a look at Wikipedia's article on Sorting Algorithms. No need to understand all of them - some get quite complex!

However, you don't have to write a sorting algorithm yourself to use one! Java has some built in for you.

import java.util.Arrays; // or java.util.Collections if you are using ArrayList etc
Arrays.sort(my_array); // this will sort your array for you, using the Quicksort algorithm

As @JS1 mentioned, your formula for finding the center is wrong, and should be

int center = start + (end - start) / 2;

And with that, you can simply return the center index of the array, since it's all sorted now!

public static int medianOfThree(int[] sample, int start, int end) {
 Arrays.sort(sample);
 return sample[start + (end - start) / 2];
}

...Unless the array has a length that is an even number. Then the median formula is a little different:

public static int medianOfFour(int[] sample, int start, int end) {
 Arrays.sort(sample);
 int medianRightIndex = start + (end - start) / 2;
 int medianLeftIndex = medianRightIndex - 1;
 return (sample[medianRightIndex] + sample[medianLeftIndex]) / 2;
}

However, unless you are specifying a range in the array (e.g. you only wanted the median of the first 3 elements), you don't need to specify the start and end parameters at all. start can be 0 and end can be sample.length. Again, this is only if you want the median of the entire array. For a specific subset, you'd still use start and end parameters.

Now we have arrived to:

public static int median(int[] sample) {
 Arrays.sort(sample);
 int median = 0;
 int index = sample.length / 2;
 if(sample.length % 2 == 0) {
 median = (sample[index] - sample[index - 1]) / 2;
 } else {
 median = sample[index];
 }
 return median;
}
answered Jul 1, 2016 at 18:33
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.