我正在寻找算法。
给N个用户。每N个用户从Z中提交1个Q选项的排名列表(Z> Q)。每个用户的Q选项都不同。
这可以应用于水果。N个用户排名。
[passion fruit, apple, orange, pear, cherry, blueberry, banana]
[blueberry, pear, cherry, banana]
[passion fruit, blueberry, banana, apple, orange]
.... ETC
我也希望能够在每个新条目上进行更新。您最聪明,最好或最有效的解决方案是什么,请说明并说明原因?非常感谢您。
编辑:为了回应评论,我举了一个例子。我想要一个水果排名网站。用户可以访问该站点,对他或他尝试过的所有水果类型进行排名,这就是排名的“投票”。主列表显示总体排名。因此,我想人们最喜欢的品尝水果*。该算法虽然适用于任何事物。
您可以做的是将平均排名存储在每个水果中,最终的整体排名列表可以按水果的平均排名进行排序。对于您给出的示例,passion fruit
的排名两次为0,因此平均排名为0。blueberry
在三个条目中的排名为5、0和1,因此平均排名为2。最终的总体排名列表将以passion fruit
和其他按平均等级排序的水果开头。
Map<String, int[]> fruitToRank = new HashMap<String, int[]>();
//key is name of the fruit
//val[0] is sum of ranks and val[1] is vote counts for the fruit
void newEntry(String[] rank) {
for (int i = 0; i < rank.length; i++) {
String fruitName = rank[i];
if (fruitToRank.containsKey(fruitName)) {
int[] rankInfo = fruitToRank.get(fruitName);
rankInfo[0] += i; //add rank to sum of ranks
rankInfo[1]++; //number of vote counts
} else {
int[] rankInfo = new int[] {i, 1};
fruiteToRank.put(fruitName, rankInfo);
}
}
int[] getNFavoriteFruits(int n) {
int[] result = new int[n];
//fruit with lower number as average rank has higher priority
PriorityQueue<String> pq = new PriorityQueue<String>((s1, s2) -> {
int[] rankInfo1 = fruitToRank.get(s1);
int[] rankInfo2 = fruitToRank.get(s2);
double averageRank1 = (double)rankInfo1[0] / rankInfo1[1];
double averageRank2 = (double)rankInfo2[0] / rankInfo2[1];
return averageRank1 - averageRank2;
});
for (String k: fruitToRank.keySet()) {
pq.add(k);
}
for (int i = 0; i < n; i++) {
result[i] = pq.poll();
}
return result;
}