如果您想确定,您列出的是前 100 名,那么您是对的。
您可以为此编写一些启发式方法。例如,您可以记录前 100 个和最后 100 个。新的 100 将是第二个将是第二个列表,其中的 url 可能成为前 100 个之一。最后 100 个您可以算作前 100 个。如果您访问的 url 不是在前 100 名和最后 100 名中,您将从最后 100 名中删除 sth,即最后访问的 url。
如果 sb 一个一个地访问 101 个 url,它不会起作用,但这是一个好的开始。您可以考虑不同的策略,应该删除哪个策略等等。
示例实现:
top100 : list<(URL, count)>
last100: list<(URL, count, score)>
process(URL){
if(URL in top100) incrementCount top100[URL];
elif(URL in last100){
incrementScore last100[URL];
newCount := incrementCount last100[URL];
if (newCount > top100.lowestCount)
swap this URL between last100 and top100
}
else{
//perform check if should change sth in last100, i.e.:
if(exists score=0 in last100)
remove score0 from last100.
put (URL, 1, 0) to last100;
}
else{
decrement all score in last100
}
}
}
top/last 3 而不是 100 的简单运行。让我们从中间开始,当:top3 = [ (A, 10), (B, 4), (C, 3) ] last3 = [ (E, 2, 0) , (F, 1, 0), (G, 1, 0) ] (A..G 是 URL)
G: last3 = [ (E, 2, 0), (G, 2, 1), (F, 1, 0) ] //inc G score, count
G: last3 = [ (E, 2, 0), (G, 3, 2), (F, 1, 0) ] //inc G score, count
H: last3 = [ (E, 2, 0), (G, 3, 2), (H, 1, 0) ] //用 H 代替 F
F: last3 = [ (E, 2, 0), (G, 3, 2), (F, 1, 0) ] //用 F 代替 G
G:top3 = [ (A, 10), (B, 4), (G, 4) ], [ (E, 2, 0), (C, 3, 2), (F, 1, 0) ] / /交换GC
G: top3 = [ (A, 10), (B, 4), (G, 5) ] // 增加 G 计数
F: last3 = [ (E, 2, 0), (G, 3, 2), (F, 2, 1) ] //inc F score, count
E: last3 = [ (E, 3, 1), (G, 3, 2), (F, 2, 1) ] //inc E score, count
H: last3 = [ (E, 3, 0), (G, 3, 1), (F, 2, 0) ] //no el with score=0, dec all scores
H: last3 = [ (E, 3, 0), (G, 3, 1), (H, 1, 0) ] //用 H 代替 F
所以F和G经常出现,但不幸的是他们阻止了对方保持在last3,并进入top3。在具有 last/top100(或更多)的实际情况中,很难发生这种情况。
更复杂的策略应该操纵分数和计数,以更好地决定是否应该放置新的 url,如果是,应该删除哪个 url。您应该准备一些样本数据并创建高质量的策略。