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