Skip to content

Instantly share code, notes, and snippets.

@jdiscar
Created February 24, 2014 19:30
Show Gist options
  • Save jdiscar/9195270 to your computer and use it in GitHub Desktop.
Save jdiscar/9195270 to your computer and use it in GitHub Desktop.
R's order() function in Java
/*
* 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