Returning Largest 5 indexs Of Array of double

Okay here is the deal,I have a double[] of size N, I need to return in an int[] the 5 index values of the 5 largest doubles in the double[] array. int[] fiveBiggest = findBiggestFiveIndexes(double[] input);Anyone got a fast algorithm for this?
[271 byte] By [mm_treoa] at [2007-10-2 5:44:40]
# 1

Simple linear code, though with some overhead.

public Set findLargest(double[] input, int top) {

SortedMap sm = new SortedMap();

for (int i=0;input.length;i++) {

sm.put(new Double(input[i]), new Integer(i));

if (sm.size()>top) {

sm.remove(sm.firstKey());

}

}

return sm.keySet();

}

parza at 2007-7-16 1:54:39 > top of Java-index,Other Topics,Algorithms...
# 2
Sorry return sm.values();
parza at 2007-7-16 1:54:39 > top of Java-index,Other Topics,Algorithms...
# 3
SortedMap sm = new SortedMap() ?I am trying to find something that doesn't include using util classes/interfacesThank's though
mm_treoa at 2007-7-16 1:54:39 > top of Java-index,Other Topics,Algorithms...
# 4
> I am trying to find something that doesn't include> using util classes/interfacesWhy not make use of the util package? If it's a homework assignment, then please show what you've got sofar, and you will definitely get help from others.
prometheuzza at 2007-7-16 1:54:39 > top of Java-index,Other Topics,Algorithms...
# 5

This is not a homework assignment. I don't mind if util classes are used, it's just that most of the time they slow things down.

I just need a speedy way of doing this

int[] biggestFiveIndexes = findBiggestFiveIndexes(double[] input);

public int[] findBiggestFiveIndexes(double[] input) {

int[] temp = new int[5];

// I tried finding the initial biggest then storing this, then comparing

// the next biggest with the stored and so on... but no such luck.

// just can't think straight as well as making it efficient

return temp;

}

mm_treoa at 2007-7-16 1:54:39 > top of Java-index,Other Topics,Algorithms...
# 6

> This is not a homework assignment. I don't mind if

> util classes are used, it's just that most of the

> time they slow things down.

I doubt that.

> I just need a speedy way of doing this

Maybe you can do something with the built in sort method of java.util.Arrays? Here's a example:

int top = 5;

double[] array = {1.1, 6.3, 2.8, 11.5, 99.2, 10.9, 8.0, 13.3};

java.util.Arrays.sort(array);

for(int i = array.length-1; i > array.length-1-top; i--) {

System.out.println(array[i]);

}

Good luck.

prometheuzza at 2007-7-16 1:54:39 > top of Java-index,Other Topics,Algorithms...
# 7

> ... it's just that most of the time they slow things down.

> I just need a speedy way of doing this

Pre-optimization is almost always a really bad idea.

Time consumption is usually really hard to predict because

of things like overhead, algorithm complexity, and 10-90

role. When avoiding using simple algorithms you will most

likely code more bugs, which will take longer to find.

If you are working under any deadline pressure, my advice

is to code the simplest solution you can come up with and

then change it when your time consumption analysis tool

tells you that you must.

However, if you are a student or just coding for fun,

pre-optimization is a really good way to learn.

parza at 2007-7-16 1:54:39 > top of Java-index,Other Topics,Algorithms...
# 8

> Maybe you can do something with the built in sort

> method of java.util.Arrays? Here's a example:

> int top = 5;

> double[] array = {1.1, 6.3, 2.8, 11.5, 99.2,

> 9.2, 10.9, 8.0, 13.3};

>java.util.Arrays.sort(array);

>

> for(int i = array.length-1; i >

> i > array.length-1-top; i--) {

>System.out.println(array[i]);

>}

> Good luck.

Thank's, but I can't sort the array as I need the original index values, as the index values refer to something else, so they need to be kept in tact.

I'll keep trucking along

mm_treoa at 2007-7-16 1:54:39 > top of Java-index,Other Topics,Algorithms...
# 9

> Thank's, but I can't sort the array as I need the

> original index values, as the index values refer to

> something else, so they need to be kept in tact.

Oh yeah, forgot that.

Well here's a way to do it without using a java.util package (I only used it for printing). Be carefull though, if you take a value for 'n' that is near the size of your array of double's, you'll end up with an O(n^2) algortihm.

class Test {

// main-method

public static void main(String[] args) {

double[] array = {1.0, 9.0, 8.0, 5.0, 6.0, 4.0, 2.0, 3.0, 7.0};

int[] biggestFiveIndexes = findBiggestFiveIndexes(array, 5);

System.out.println(java.util.Arrays.toString(array));

System.out.println(java.util.Arrays.toString(biggestFiveIndexes));

}

// Find all 'n' biggest index-numbers of an array of doubles

private static int[] findBiggestFiveIndexes(double[] array, int n) {

double[] copy = copyArray(array);

int[] top = new int[n];

int size = 0;

while(size < n) {

top[size] = getNextBiggest(copy);

size++;

}

return top;

}

// Return the index of the biggest value and reset

// that specific value so it will only be found once.

private static int getNextBiggest(double[] array) {

int biggestIndex = 0;

double biggestValue = array[biggestIndex];

for(int i = 1; i < array.length; i++) {

if(array[i] > biggestValue) {

biggestIndex = i;

biggestValue = array[i];

}

}

array[biggestIndex] = Double.MIN_VALUE;

return biggestIndex;

}

// Return a copy of an array

private static double[] copyArray(double[] array) {

double[] copy = new double[array.length];

for(int i = 0; i < array.length; i++) {

copy[i] = array[i];

}

return copy;

}

}

I'm sure there will be far better (and faster) methods to do it, but this will give you a start.

Good luck.

prometheuzza at 2007-7-16 1:54:39 > top of Java-index,Other Topics,Algorithms...
# 10

I tested it using prometheuzz's test case only.

/**

Only use this method if index.length is a small constant.

Stores the index location of the n largest values (in no

particular order) in the index array, where n == index.length.

If index.length is not a constant, then using a general selection

algorithm (e.g. median finding) would be better.

*/

public static void getLargest(double[] data, int[] index) {

int k = 0;

for (int i = 0; i < data.length; i++) {

double d = data[i];

int j = 0;

for (; j < k; j++) {

if (d > data[index[j]])

break;

}

if (j < index.length) {

if (k < index.length) {

index[k++] = i;

}

else {

// at this point we want to replace the smallest value

double smallest = Double.MAX_VALUE;

int smallestIndex = -1;

for (int z = 0; z < index.length; z++) {

double e = data[index[z]];

if (e < smallest) {

smallest = e;

smallestIndex = z;

}

}

if (smallestIndex != -1)

index[smallestIndex] = i;

}

}

}

}

rkippena at 2007-7-16 1:54:39 > top of Java-index,Other Topics,Algorithms...
# 11

Slightly cleaner version:

public static void getLargest(double[] data, int[] index) {

int k = 0;

for (int i = 0; i < data.length; i++) {

double d = data[i];

if (k < index.length) {

index[k++] = i;

}

else {

double smallest = Double.MAX_VALUE;

int smallestIndex = -1;

for (int j = 0; j < index.length; j++) {

double e = data[index[j]];

if (d > e) {

// is e the smallest?

if (e < smallest) {

smallest = e;

smallestIndex = j;

}

}

}

if (smallestIndex != -1) index[smallestIndex] = i;

}

}

}

rkippena at 2007-7-16 1:54:39 > top of Java-index,Other Topics,Algorithms...
# 12

public int[] findTop(double[] values, int count)

{

int[] top = new int[count];

int lowestIndex = 0;

for (int i = 0; i < values.length; i++)

{

if (i < count)

{

top[i] = i;

if (values[i] < values[lowestIndex])

{

lowestIndex = i;

}

continue;

}

if (values[i] > values[top[lowestIndex]])

{

top[lowestIndex] = i;

for (int n = 0; n < top.length; n++)

{

if (values[top[n]] < values[top[lowestIndex]])

{

lowestIndex = n;

}

}

}

}

return top;

}

Nothing spectactular but might be relatively fast.

kablaira at 2007-7-16 1:54:39 > top of Java-index,Other Topics,Algorithms...
# 13

I didn't like the formatting.

public int[] findTop(double[] values, int count) {

int[] top = new int[count];

int lowestIndex = 0;

for (int i = 0; i < values.length; i++) {

if (i < count) {

top[i] = i;

if (values[i] < values[lowestIndex]) {

lowestIndex = i;

}

continue;

}

if (values[i] > values[top[lowestIndex]]) {

top[lowestIndex] = i;

for (int n = 0; n < top.length; n++) {

if (values[top[n]] < values[top[lowestIndex]]) {

lowestIndex = n;

}

}

}

}

return top;

}

kablaira at 2007-7-16 1:54:39 > top of Java-index,Other Topics,Algorithms...
# 14

> This is not a homework assignment.

i doubt it too.

> I don't mind if util classes are used, it's just that most of the time they

> slow things down.

why would you think that. Java use a modified and optimized merge sort for most of their collection classes. Millions of people have use it..don't you think Java people would have optimized it by now (and not to mention any bug would have been fixed by now)?

Don't be afraid to use java.util classes. Only when you find the solution

is too slow (after profiling your application..and saw the cause is the

java.util class), then you might consider writing your own collection

class...or better yet..check out other available collection classes before you write one your own..like the Jakarta Common Collections.

tnguyen1973a at 2007-7-16 1:54:39 > top of Java-index,Other Topics,Algorithms...