Java 计算项目的出现次数

Java 计算项目的出现次数,java,algorithm,data-mining,Java,Algorithm,Data Mining,我正试图找出以下问题的最佳解决方案(Java): 在第一次传递某些数据时,我计算项目的出现次数。基本上,我创建了一个从item ID到integer的HashMap,并在每次看到该项出现时递增该整数。所以基本上,我有一个从itemID到count的映射 现在,我需要从这个映射中得到按计数排序的前n个条目ID 显然,HashMap不是这里的最佳数据结构。有什么想法吗 这是我在工作中做的一些数据挖掘工作,所以不是硬件问题…一个明显的答案是使用分类地图。确保新创建的映射的可比较属性使顶部项成为第一项,

我正试图找出以下问题的最佳解决方案(Java):

在第一次传递某些数据时,我计算项目的出现次数。基本上,我创建了一个从item ID到integer的HashMap,并在每次看到该项出现时递增该整数。所以基本上,我有一个从itemID到count的
映射

现在,我需要从这个映射中得到按计数排序的前n个条目ID

显然,HashMap不是这里的最佳数据结构。有什么想法吗


这是我在工作中做的一些数据挖掘工作,所以不是硬件问题…

一个明显的答案是使用分类地图。确保新创建的映射的可比较属性使顶部项成为第一项,并且您可以从中获取第一个元素

一个显而易见的答案是使用分类地图。确保新创建的映射的可比较属性使顶部项成为第一项,并且您可以从中获取第一个元素

实际上,HashMap在这里是一个合理的解决方案,因为您必须累积总数。在知道所有项目的计数之前,您无法快捷地找到前N个项目,也无法简单地找到前N个项目

在获得HashMap之后,有几种方法可以完成一些事情。如果数据相对较小,则创建一个itemId和count对数组,并按计数降序排序。然后选择前N项

如果您有很多项(数十万项),那么在获得计数后使用最小堆可能会更快,其思想是将前N个项放入最小堆,然后仅在其计数大于最小堆中的最小项时插入一个项


在进行相加时,您可以通过计数来保持事物的有序性,但每次递增计数器时,您都必须从集合中删除该事物并重新插入它。您最好在HashMap中累积数据,这样可以很容易地按ID查找数据,然后在后期处理中按计数应用排序。

实际上,HashMap是一个合理的解决方案,因为您必须累积总数。在知道所有项目的计数之前,您无法快捷地找到前N个项目,也无法简单地找到前N个项目

在获得HashMap之后,有几种方法可以完成一些事情。如果数据相对较小,则创建一个itemId和count对数组,并按计数降序排序。然后选择前N项

如果您有很多项(数十万项),那么在获得计数后使用最小堆可能会更快,其思想是将前N个项放入最小堆,然后仅在其计数大于最小堆中的最小项时插入一个项


在进行相加时,您可以通过计数来保持事物的有序性,但每次递增计数器时,您都必须从集合中删除该事物并重新插入它。您最好在HashMap中累积内容,这样可以很容易地按ID查找内容,然后通过后处理应用计数排序。

我会在计数后对结果进行排序

Map<Item,Integer> map = new HashMap<Item, Integer>();

... (fill the map, counting the occurences)

List<Map.Entry<Item, Integer>> list = new ArrayList<Map.Entry<Item, Integer>>(map.size());
list.addAll(map.entrySet());
Collections.sort(list, new Comparator<Map.Entry<Item, Integer>>() {
    public int compare(Map.Entry<Item, Integer>> left, Map.Entry<Item, Integer>> right) {
       // "-" to invert the order
       return - left.getValue().compareTo(right.getValue());
    }
});
Map Map=newhashmap();
... (填写地图,统计发生的事件)
List List=新的ArrayList(map.size());
list.addAll(map.entrySet());
Collections.sort(list,newcomparator(){
公共整数比较(Map.Entry>left,Map.Entry>right){
//“-”以反转顺序
return-left.getValue().compareTo(right.getValue());
}
});
现在,
list
是一个按计数排序(降序)的列表,
。子列表(0,n)
将给出前n个


如果你的
n
比项目总数小得多,那么这不是最优的-我认为有一种更好(但更复杂)的算法,只取无序列表中最好的部分。

我会在计数后对结果进行排序

Map<Item,Integer> map = new HashMap<Item, Integer>();

... (fill the map, counting the occurences)

List<Map.Entry<Item, Integer>> list = new ArrayList<Map.Entry<Item, Integer>>(map.size());
list.addAll(map.entrySet());
Collections.sort(list, new Comparator<Map.Entry<Item, Integer>>() {
    public int compare(Map.Entry<Item, Integer>> left, Map.Entry<Item, Integer>> right) {
       // "-" to invert the order
       return - left.getValue().compareTo(right.getValue());
    }
});
Map Map=newhashmap();
... (填写地图,统计发生的事件)
List List=新的ArrayList(map.size());
list.addAll(map.entrySet());
Collections.sort(list,newcomparator(){
公共整数比较(Map.Entry>left,Map.Entry>right){
//“-”以反转顺序
return-left.getValue().compareTo(right.getValue());
}
});
现在,
list
是一个按计数排序(降序)的列表,
。子列表(0,n)
将给出前n个


如果你的
n
比项目总数小得多,那么这不是最优的-我认为有一种更好(但更复杂)的算法,只取无序列表中最好的部分。

我认为如果你想获得ID,计算并保持映射结构,您需要创建一个类来封装数据

public class DataPair implements Comparable<DataPair> {
    private long id;
    private Integer count;

    //Getters and setters

    public void increaseCount() {
        count++;
    }

    public int compareTo(DataPair dp) {
         return this.count.compareTo(dp.count);
    }

}
公共类数据对实现可比较{
私人长id;
私有整数计数;
//接球手和接球手
公共无效增量计数(){
计数++;
}
公共整数比较(数据对dp){
将此.count.compareTo返回(dp.count);
}
}
然后制作一张地图,就像你一直在使用的那样:

Map<long, DataPair> m = new HashMap<long, DataPair>()
Map m=newhashmap()
然后,当需要按计数排序时,只需取出值并进行排序,同时保持按id获取当前计数的能力

List<DataPair> list = new ArrayListM<DataPair>(m.values());
Collections.sort(list);
List List=newarraylistm(m.values());
集合。排序(列表);

然后,您将拥有已排序的计数,并且仍然能够获取ID。

我认为,如果您希望能够获取ID,那么您需要创建一个类来封装数据,并仍然保持映射结构

public class DataPair implements Comparable<DataPair> {
    private long id;
    private Integer count;

    //Getters and setters

    public void increaseCount() {
        count++;
    }

    public int compareTo(DataPair dp) {
         return this.count.compareTo(dp.count);
    }

}
公共类数据对实现可比较{
私人长id;
私有整数计数;
//接球手和接球手
公共无效增量计数(){
计数++;
}
公共整数比较(数据对dp){
将此.count.compareTo返回(dp.count);
}
}

public final class ProfileComparator implements Comparator<Profile> { public int compare(final Profile n1, final Profile n2) { if (n1.getValue() > n2.getValue()) { return -1; } if (n2.getValue() > n1.getValue()) { return 1; } return 0; } }