[英]How to sort Enums by Counting Sort?
例如,我要对Enum进行排序。 我有一个键为Enum
的对象
更新
public class Main {
public static void main(String[] args) throws Exception {
Bean[] mass = new Bean[] { new Bean(new Object(), A), new Bean(new Object(), C), new Bean(new Object(), D),
new Bean(new Object(), B), new Bean(new Object(), A) }; // 1, 3, 4, 2, 1
Arrays.sort(mass, new EnumComparator());
System.out.println(Arrays.toString(mass)); //[1, 1, 2, 3, 4]
}
}
class EnumComparator implements Comparator<Bean> {
@Override
public int compare(Bean o1, Bean o2) {
return o1.key.toString().compareTo(o2.key.toString());
}
}
class Bean {
public Object data;
public Enum key;
public Bean(Object data, Enum key) {
super();
this.data = data;
this.key = key;
}
@Override
public String toString() {
return key.toString();
}
}
enum MyEnum {
D("4"),
A("1"),
B("2"),
C("3");
private String index;
private MyEnum(String index) {
this.index = index;
}
@Override
public String toString() {
return index;
}
}
排序Arrays.sort
使用TimSort
或MergeSort
到平均运行O (n log n)
。 但是,如果我们使用有限数量的常量( Enums
),则可以使用时间O (n)
的计数排序 。 有没有一种标准的机制可以在java
对Enums
使用计数排序?
如果事先知道常量的顺序,则可以使用HashMap
来实现计数排序:
List<MyEnum> countingSort(MyEnum order[], List<MyEnum> input) {
HashMap<MyEnum, Integer> countMap = new HashMap<>();
for (MyEnum obj : input) {
countMap.put(obj, countMap.getOrDefault(obj, 0) + 1);
}
List<MyEnum> result = new ArrayList<>();
for (MyEnum obj : order) {
for (int i = 0; i < countMap.getOrDefault(obj, 0); ++i) {
result.add(obj);
}
}
return result;
}
public static void main (String[] args) {
MyEnum order[] = {A, B, C, D};
List<MyEnum> input = Arrays.asList(D, C, A, B, D, D, B, A, A, C, D);
List<MyEnum> res = countingSort(order, input);
}
这种方法的复杂度平均为O(n)
。
在问题的更新版本中,您正在询问鸽孔排序 。 它类似于计数排序,但有其自己的名称。 我们需要对上述算法进行一些更改。 首先,我们需要将HashMap<MyEnum, Integer>
替换为HashMap<MyEnum, Integer>
HashMap<MyEnum, List<Bean>>
,并将所有Bean
对象存储在相应的列表中。 然后,在迭代输入之后,我们需要以指定顺序连接所有列表。
一个明显的非答案是:不要。
不用担心O(n)vs O(n * log(n))。 担心编写随时间可以维护和增强的人类可读代码。
有两种情况:
长话短说:这听起来像是典型的过早优化。 然后唯一有效的答案是:专注于编写干净,优雅的代码以完成工作。 然后使用真实数据进行测量 。 然后确定是否需要采取进一步的措施(大多数情况下:不需要)。
好的,没有讨论我们应该使用O(n)
还是O(nlogn)
就足够了。 无论如何,可能您可以实现自定义counting sort
算法? (我不记得我知道的任何lib都有这个):
private static void countSort(Bean[] mass) {
List<Bean>[] arr = (List<Bean>[])new List[MyEnum.values().length];
for (Bean bean : mass) {
int pos = Integer.parseInt(bean.key.getIndex()) - 1;
if (arr[pos] == null)
arr[pos] = new ArrayList<>();
arr[pos].add(bean);
}
int i = 0;
for (List<Bean> beans : arr)
for (Bean bean : beans)
mass[i++] = bean;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.