【发布时间】:2016-12-14 03:01:24
【问题描述】:
以下代码提供了一个简单版本的类,它跟踪输入字符串的频率(方法 addPV),并可以按顺序输出具有最高计数的 k 个字符串(方法 firstK)。
在下面的简化代码中,二叉搜索树(treeset)用于跟踪计数并保持顺序。二级数据结构(哈希图)用于快速访问树集中的元素。使用包含字符串名称和计数的复合条目类,其中计数确定自然顺序,名称为 hashCode。
最优雅的方法是使用 BST(例如树形图),其条目将以计数作为键,将字符串名称作为值。内部哈希图可用于在恒定时间内有效地访问 BST 中的条目。通用库中是否有标准数据结构可以为通用对象执行此操作?
import java.util.*;
public class MostVisitedPages {
private HashMap<String,CountEntry> hm = new HashMap<>();
private TreeSet<CountEntry> ts = new TreeSet<>();
private static class CountEntry implements Comparable<CountEntry>{
String page;
int count;
CountEntry (String page, int count){
this.page = page;
this.count = count;
}
@Override
public int compareTo(CountEntry entry){
int res = Integer.compare(count,entry.count);
return res != 0 ? res: page.compareTo(entry.page);
}
@Override
public boolean equals(Object obj){
if(this == obj) return true;
else if (obj==null || !(obj instanceof CountEntry)) return false;
else {return page.equals(((CountEntry)obj).page);}
}
@Override
public int hashCode(){
return page.hashCode();
}
}
public void addPV(String p){
if(hm.containsKey(p)){
CountEntry ce = hm.get(p);
ts.remove(ce);
ce.count += 1;
ts.add(ce);
} else {
CountEntry ce = new CountEntry(p,1);
ts.add(ce);
hm.put(p, ce);
}
}
public List<String> firstK(int k){
List<String> ret = new ArrayList<>(k);
Iterator<CountEntry> it = ts.descendingIterator();
for(int i = 0; i<k && i<hm.size(); i++){
ret.add(it.next().page);
}
return ret;
}
}
【问题讨论】:
标签: java data-structures hashmap treemap