Java rarrange枚举数组

Java rarrange枚举数组,java,Java,我想知道如何对enum重新排序,以便所有山羊都位于数组的开头,所有绵羊都位于数组的末尾。现在它确实起作用了,但是直到数组大小>100。。重新排序的速度也很重要,因此api方法有点太慢。有什么建议吗 public class Sheep { enum Animal {sheep, goat}; public static void main (String[] param) { reorder(Animal.values()); } public stat

我想知道如何对enum重新排序,以便所有山羊都位于数组的开头,所有绵羊都位于数组的末尾。现在它确实起作用了,但是直到数组大小>100。。重新排序的速度也很重要,因此api方法有点太慢。有什么建议吗

public class Sheep {


   enum Animal {sheep, goat};

   public static void main (String[] param) {

    reorder(Animal.values());
   }

   public static void reorder (Animal[] animals) {


       int l, r, i, j;

       i = l = 0; //left most element
       r = animals.length - 1;//right most element
       int mid = (r+l)/2; // middle element of the array
        for(i=0; i < animals.length;i++)
        {
            if(i < mid)
            {
                animals[i] = animals[l+1];

                System.out.println(animals[r]);

            } else if(i >= mid )
            {   
                animals[i] = animals[r-1];
                System.out.println(animals[r]);

            }

        }

   }
}
公共类绵羊{
枚举动物{绵羊、山羊};
公共静态void main(字符串[]参数){
重新排序(Animal.values());
}
公共静态无效重新排序(动物[]动物){
int l,r,i,j;
i=l=0;//最左边的元素
r=anives.length-1;//最右边的元素
int mid=(r+l)/2;//数组的中间元素
对于(i=0;i=mid),则为else
{   
动物[i]=动物[r-1];
系统输出println(动物[r]);
}
}
}
}

由于
枚举
实现了
可比
,因此您可以简单地对数组进行排序,然后反转数组:

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;
    }
}
(感谢贝什·古龙的创意。)

编辑:如果您必须处理两个值,只需从两端扫描,在发现两个元素顺序不正确时交换,您可以做得更好:

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;
        }
    }
}
公共静态无效重新排序(动物[]动物){
int first=0;
int last=动物。长度-1;
while(第一次<最后一次){
/*
*未排序的元素位于位置first..last(包括)。
*首先之前的一切都是更高级的动物;之后的一切都是更高级的动物
*最后是低等动物。
*/
while(动物[first].ordinal()==1&&first

但是,如果您只需要生成正确的输出(而不是对数组进行实际排序),那么@ajb在评论中建议的方法是最好的:只需数一数有多少只绵羊和山羊,并多次打印相应的值。

如果您想在这种特殊情况下获得最大性能,您只需数一数两个可能值中的一个值,并相应地覆盖数组即可获得排序将创建的结果:

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);
}


您可以将其视为的修改版本。

发布在我之前;)。Sry,但是你最后在哪里声明int?或者它的价值是什么?我想知道这是否比仅仅做
Arrays.sort(arr,Collections.reverseOrder())更好@user3024888-抱歉。那是一个打字错误(现已修复)。它应该是
j
。呵呵,是的,我想出来了,有趣的是它还没有通过junit测试,有点太慢了,花了3079秒,但肯定是<2500秒。但还是要谢谢你!既然这些都是简单的
enum
s,您就不能只计算山羊的数量,然后用
N
山羊和
length-N
绵羊构建一个数组吗?当域只有两种可能性时,使用排序算法没有多大意义。我不确定您的算法在做什么,但它似乎比要求的复杂。注意:
Enum#values()
是一个O(n)操作,因为每次调用它时它都会克隆值数组。这是为了避免你在这里做的事情。因此,如果重新排列数组,请保留引用-原始值将保持不变。@Obicere-
values()
在此程序中只调用一次。不需要保留引用。@TedHopp是的,但是对于这个精确的程序,重新排序的结果(调试打印除外)被忽略,因为他没有保留对值的引用。
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;
        }
    }
}
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);