Java rarrange enum array

后端 未结 2 778
無奈伤痛
無奈伤痛 2021-01-22 18:11

i was wondering how can i reorder enum so that all goats are at the beginning and all sheep are at the end of the array. Right now it actually does the trick but until the arra

相关标签:
2条回答
  • 2021-01-22 18:31

    If you want to have maximum performance for such a special case you may simply count the number of one of the two possible values and overwrite the array accordingly to get the result that sorting would create:

    public static void reorder (Animal[] animals) {
        assert Animal.values().length==2;
        int numGoat=0;
        for(Animal a:animals) if(a==Animal.goat) numGoat++;
        Arrays.fill(animals, 0, numGoat, Animal.goat);
        Arrays.fill(animals, numGoat, animals.length, Animal.sheep);
    

    }

    You can see it as a modified version of counting sort.

    0 讨论(0)
  • 2021-01-22 18:41

    Since an enum implements Comparable, you can simply sort and then reverse the array:

    public static void reorder(Animal[] animals) {
        Arrays.sort(animals);
        for (int i = 0, j = animals.length - 1; i < j; ++i, --j) {
            Animal tmp = animals[i];
            animals[i] = animals[j];
            animals[j] = tmp;
        }
    }
    

    You might also be able to do it with:

    List<Animal> list = Arrays.asList(animals);
    Collections.sort(list);
    Collections.reverse(list);
    

    This basically does the same thing with API calls with the (very slight) overhead of wrapping the array in a List object. You can even do this:

    Arrays.sort(animals, Collections.reverseOrder());
    

    (Thanks to Bhesh Gurung for the idea.)

    EDIT: If you have to deal with exactly two values, you can do much better by simply scanning from both ends, swapping as you find two elements out of order:

    public static void reorder(Animal[] animals) {
        int first = 0;
        int last = animals.length - 1;
        while (first < last) {
            /*
             * The unsorted elements are in positions first..last (inclusive).
             * Everything before first is the higher animal; everything after
             * last is the lower animal.
             */
            while (animals[first].ordinal() == 1 && first < last) {
                ++first;
            }
            while (animals[last].ordinal() == 0 && first < last) {
                --last;
            }
            if (first < last) {
                /*
                 * At this point, the sort conditions still hold and also we know
                 * that the animals at first and last are both out of order
                 */
                Animal temp = animals[first];
                animals[first] = animals[last];
                animals[last] = temp;
                ++first;
                --last;
            }
        }
    }
    

    However, if all you need to do is generate the right output (and not actually sort the array), then the approach suggested by @ajb in a comment is the best: just count how many sheep and goats there are and print the corresponding values that many times.

    0 讨论(0)
提交回复
热议问题