2

I have an array of

double[] weights = { 32.0, 32.0, 25.0, 25.0, 30.0, 28.0,
                     12.0, 10.0,  8.0,  8.0, 18.0,  0.0 };

I want to sort its corresponding indices 0 through 11 according to a descending sort of weights:

{ 32.0, 32.0, 30.0, 28.0, 25.0, 25.0, 18.0, 12.0, 10.0, 8.0, 8.0, 0.0 }

My desired output, in this case, would be an int[]:

{ 0, 1, 4, 5, 2, 3, 10, 6, 7, 8, 9, 11 }

I have added an int[] values to keep track of indices:

int[] values = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }
1
  • 1
    Oneliner in Scala: weights.zipWithIndex.sortBy(-_._1).map(_._2). There is a library that provides similar abstractions for Java. You can use that. Commented Dec 4, 2011 at 21:57

3 Answers 3

6

Make a comparable container class, like this

class EvanContainer implements Comparable<EvanContainer> {
    double weight;
    int value;

    EvanContainer(double w, int v) { weight = w; value = v; }

    public int compareTo(EvanContainer other) {
        return Double.compare(weight, other.weight);
    } 

}

Then you can sort that as normal.

EvanContainer[] container = new EvanContainer[weights.length];
for(int i = 0; i < weights.length; i++) {
    container[i] = new EvanContainer(weights[i],values[i]);
}

Arrays.sort(container);
Sign up to request clarification or add additional context in comments.

6 Comments

this solution, unlike the ones using map (and not multimap) allows repeated values in the double array
this looks great, glowcoder. unfortunately i'm getting a printout: EvanContainer@10c832d2 EvanContainer@47808199 EvanContainer@45bc887b EvanContainer@5ca46701 EvanContainer@2d66a22b EvanContainer@2d20cc56 EvanContainer@4447393f EvanContainer@1fff7a1e EvanContainer@3daa57fb EvanContainer@7a763f5d EvanContainer@693a317a EvanContainer@6b86768e. Any idea why?
i believe the issue is in: container[i] = new EvanContainer(weights[i],values[i]); but i may be mistaken
@Evan the class I gave you isn't 100% complete. You'll should implement the toString() method to get a good printout like that. Something like public String toString() { return "value=" + value + " weight=" + weight; } should work.
that works perfectly! how can i export just the new sorted values to a new int array?
|
1

I had this problem recently and glowcoder's answer is certainly the cleanest and simplest answer. The problem I had with that particular approach, is that it requires you to "box" every element you want to compare. Now if you have a very large number of elements in a primitive array, you don't really want to wrap every element in a object and then use Comparable to sort the wrapped objects because of the performance implications.

So I designed the following solution, which is available in Java as open-source code under the GPL here : http://open.trickl.com/trickl-sort/index.html

The sort algorithms presented allow the specification of a "Permutator". The StandardPermutator just reorders elements in an array as requested (e.g. swaps two elements at different indices). The PairedPermutator also performs the same permutation on a different array (in this case, the indices array).

This way I can use the same efficient sort algorithm on a primitive array and additionally keep track of the index rearrangement without ever boxing the values in the array. That's the theory anyway, I've not done any actual performance comparisons... Either way, I hope the library presented gives a more flexible approach to sorting.

Comments

0

A Map might be a good backing structure—it keeps your values and indices in paired groups.

Comments

Your Answer

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.