Created
February 24, 2014 19:30
-
-
Save jdiscar/9195270 to your computer and use it in GitHub Desktop.
R's order() function in Java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* This class simulates the functionality | |
* of the order() function in R for an | |
* array of doubles. | |
* | |
* It takes in a double array and sorts it, from lowest | |
* value to the highest value. Then it returns an int[] array | |
* of the indices from the unsorted array that match | |
* the values of the sorted array. | |
* | |
* So: {5.0, 4.0, 3.0, 2.0, 1.0} | |
* Returns: {4, 3, 2, 1, 0} | |
* | |
* The original array is not modified. | |
* | |
* Example Use: | |
* double[] a = {5.0, 4.0, 3.0, 2.0, 1.0}; | |
* int[] order = ROrder.order(a); | |
*/ | |
public class ROrder { | |
public ROrder() {} | |
/** | |
* This is the public interface. It takes in a | |
* double array and sorts it, from lowest value to | |
* highest value. Then it returns an int[] array | |
* of the indices from the unsorted array that match | |
* the values of the sorted array. | |
* | |
* The original array (a) is not modified. | |
* The sorting is done via quicksort. | |
* | |
* @param a double array to be sorted | |
* @return int array of the new positions of the | |
* original indexes of the sorted double array | |
*/ | |
public int[] orderByQuicksort(double[] a) { | |
// Make a shallow copy of a to prevent modification | |
double[] a2 = a.clone(); | |
// Create int[] index, which will be modified in place | |
int[] index = new int[a.length]; | |
for( int i = 0; i < index.length; i ++ ) { | |
index[i] = i; | |
} | |
// Sort | |
orderByQuicksort(a2, index, 0, index.length - 1); | |
return index; | |
} | |
/** | |
* Recursive quicksort a[left] to a[right], keep track of index changes | |
* | |
* @param a Array being sorted, modified in place | |
* @param index Keeps track of how the original indices of @a has | |
* changed, modified in place. | |
* @param left The index of left partition | |
* @param right The index of the right partition | |
*/ | |
private void orderByQuicksort(double[] a, int[] index, int left, int right) { | |
if (right <= left) return; | |
int i = partition(a, index, left, right); | |
orderByQuicksort(a, index, left, i-1); | |
orderByQuicksort(a, index, i+1, right); | |
} | |
/** | |
* Handle sorting a partition for quicksort, keep track of index changes | |
* | |
* @param a Array being sorted, modified in place | |
* @param index Keeps track of how the original indices of @a has changed. | |
* modified in place. | |
* @param left The index to start sorting from | |
* @param right The index to stop sorting from | |
*/ | |
private int partition(double[] a, int[] index, int left, int right) { | |
int i = left - 1; | |
int j = right; | |
while (true) { | |
while (a[++i] < a[right]); // find item on left to swap | |
while (a[right] < a[--j]) // find item on right to swap | |
if (j == left) break; // don't go out-of-bounds | |
if (i >= j) break; // check if pointers cross | |
swap(a, index, i, j); // swap two elements into place | |
} | |
swap(a, index, i, right); // swap with partition element | |
return i; | |
} | |
/** | |
* Swap two elements, keep track of the index changes | |
* | |
* @param a Array being sorted, modified in place | |
* @param index Keeps track of how the original indices of @a has | |
* changed, modified in place. | |
* @param i Index to swap | |
* @param j Index to swap | |
*/ | |
private void swap(double[] a, int[] index, int i, int j) { | |
double swap = a[i]; | |
a[i] = a[j]; | |
a[j] = swap; | |
int b = index[i]; | |
index[i] = index[j]; | |
index[j] = b; | |
} | |
/** | |
* This is the static interface for one time use. It | |
* takes in a double array and sorts it, from lowest value to | |
* highest value. Then it returns an int[] array | |
* of the indices from the unsorted array that match | |
* the values of the sorted array. | |
* | |
* So: {5.0, 4.0, 3.0, 2.0, 1.0} | |
* Returns: {4, 3, 2, 1, 0} | |
* | |
* The original array (a) is not modified. | |
* | |
* @param a double array to be sorted | |
* @return int array of the new positions of the | |
* original indexes of the sorted double array | |
*/ | |
public static int[] order(double[] a) { | |
ROrder s = new ROrder(); | |
int[] index = s.orderByQuicksort(a); | |
return index; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment