[英]How to sort Enums by Counting Sort?
For example, I want to sort Enum. 例如,我要对Enum进行排序。 And I have an object with key as
Enum
我有一个键为
Enum
的对象
UPDATED 更新
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;
}
}
Sorting Arrays.sort
uses TimSort
or MergeSort
to run on average O (n log n)
. 排序
Arrays.sort
使用TimSort
或MergeSort
到平均运行O (n log n)
。 But if we use a finite number of constants ( Enums
), we can use the counting sort in time O (n)
. 但是,如果我们使用有限数量的常量(
Enums
),则可以使用时间O (n)
的计数排序 。 Is there a standard mechanism for using counting sort for Enums
in java
? 有没有一种标准的机制可以在
java
对Enums
使用计数排序?
If you know the order of the constants in advance you can use a HashMap
to implement a counting sort: 如果事先知道常量的顺序,则可以使用
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);
}
The complexity of this approach is O(n)
in average. 这种方法的复杂度平均为
O(n)
。
In the updated version of the question, you are asking about pigeonhole sort . 在问题的更新版本中,您正在询问鸽孔排序 。 It is similar to counting sort but has its own name.
它类似于计数排序,但有其自己的名称。 We need several changes in the algorithm above.
我们需要对上述算法进行一些更改。 First, we need to replace a
HashMap<MyEnum, Integer>
with HashMap<MyEnum, List<Bean>>
, and store all Bean
objects in the corresponding lists. 首先,我们需要将
HashMap<MyEnum, Integer>
替换为HashMap<MyEnum, Integer>
HashMap<MyEnum, List<Bean>>
,并将所有Bean
对象存储在相应的列表中。 Then after iteration through the input, we need to join all that lists in the specified order. 然后,在迭代输入之后,我们需要以指定顺序连接所有列表。
A distinct non answer here: don't. 一个明显的非答案是:不要。
Do not worry about O(n) vs O(n*log(n)). 不用担心O(n)vs O(n * log(n))。 Worry about writing human readable code that can be maintained and enhanced over time.
担心编写随时间可以维护和增强的人类可读代码。
There are two cases: 有两种情况:
Long story short: this sounds like a typical pre-mature optimisation. 长话短说:这听起来像是典型的过早优化。 And then the only valid answer is: focus on writing clean, elegant code that gets the job done.
然后唯一有效的答案是:专注于编写干净,优雅的代码以完成工作。 Then measure with real data.
然后使用真实数据进行测量 。 And then decide if further action is required (and most of times: it is not).
然后确定是否需要采取进一步的措施(大多数情况下:不需要)。
Ok, no discussing about should we use O(n)
or O(nlogn)
is enough. 好的,没有讨论我们应该使用
O(n)
还是O(nlogn)
就足够了。 Anyway, probably you could implement custom counting sort
algorithm? 无论如何,可能您可以实现自定义
counting sort
算法? (I do not remember that any lib I know have this): (我不记得我知道的任何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.