小数据量用全量排序 + 向前过滤的情况。采出来的位置置为null;
2021.10.19
假设有一些系列的资源,每个资源有自己的id(int)、score(doule)、type(str),
将其按score降序排序,尽量推荐给用户score高的资源;但是要求连续6条资源的type互不相同
输入: "\t"分隔, 每行一个资源:id, score, type
输出:推荐给用户的top 10的结果
step1 : 确定type类型,每一类用最大堆结构维护
public static class Item{
int id;
double socre;
String str;
// 构造函数
}
//构建候选资源池子
public static void process(Item[] items ){
HashMap<String, PriorityQueue<Item>> map = new HashMap();
for(int i = 0 ;i < item.length; i++){
if(map.containsKey(item.type)){
PriorityQueue<Item> temp = map.get(items[i].type);
temp.add(items[i]);
}else{
PriorityQueue<Item> temp = new LinkedList(new MyCompara);
temp.add(items[i]);
map.put(items[i].type, temp);
}
}
}
step2: 对每一个列表按照score大小排序,也可以将初始化的数据结构改成最小堆PriorityQueue。
step3: 轮询采样。
public static Item[] invoke(Map<String, List<Item>> map){
Item[] result = second(map, 10, 6)
}
public static Item[] second(Map<String, List<Item>> map, int n, int diff ) {
PriorityQueue<Item> maxScoreQueue= new PriorityQueue();
for(int i = 0 ; i < Math.min(diff, map.size()); i ++){
PriorityQueue curQueue = map.get(i);
maxScoreQueue.add(curQueue.poll());
}
Item[] result = new Item(n);
//尽可能按score由大到小,同时品类隔离。
int index = 0;
while(index < n){
String[] sequeceType = new String[diff];
if(index< diff){
Item curItem = maxScoreQueue.poll()
result[index++] = curItem;
sequenceType[index] = curItem.type;
}else{
String firstType = sequenceType[0];
Item attachItem = map.get(firstType).poll;
}
}
// 如果不足,需要补足;
if(index < n){
for(int i = 0 ; i < map.size(); i ++){
PriorityQueue curQueue = map.get(i);
maxScoreQueue.add(curQueue.poll());
}
while(index < n ){
if(!maxScoreQueue.isEmpty()){
result[index++] = maxScoreQueue.poll();
}else break;
}
}
}