Algorithm 为web服务器设计一个数据结构来存储访问页面的历史记录
服务器必须在过去n天内维护数据。它必须先显示当天访问量最大的页面,然后显示第二天访问量最大的页面,依此类推Algorithm 为web服务器设计一个数据结构来存储访问页面的历史记录,algorithm,data-structures,Algorithm,Data Structures,服务器必须在过去n天内维护数据。它必须先显示当天访问量最大的页面,然后显示第二天访问量最大的页面,依此类推 我在想一系列的散列图。有什么建议吗?这取决于你想要什么。例如,您是希望存储历史记录中页面的实际数据,还是仅存储URL?如果有人访问了一个页面两次,它应该在历史中出现两次吗 如果您希望存储一个页面的数据,并且希望每个页面只显示一次,则哈希映射是合适的 如果我认为更可能的是,你只想存储URL,但是希望每个存储多次,如果它被访问不止一次,那么数组/向量可能会更有意义。如果您希望看到大量(相对)长
我在想一系列的散列图。有什么建议吗?这取决于你想要什么。例如,您是希望存储历史记录中页面的实际数据,还是仅存储URL?如果有人访问了一个页面两次,它应该在历史中出现两次吗 如果您希望存储一个页面的数据,并且希望每个页面只显示一次,则哈希映射是合适的
如果我认为更可能的是,你只想存储URL,但是希望每个存储多次,如果它被访问不止一次,那么数组/向量可能会更有意义。如果您希望看到大量(相对)长URL的重复,您可以创建一组URL,并为每次访问存储某种指向相关URL的指针/索引/引用。但是,请注意,维护这一点可能会变得不那么简单。
具有日期类型键和哈希映射类型值的外部哈希映射 具有包含url的字符串类型键和包含访问计数的int类型值的内部哈希映射 C#中的示例://外部哈希映射
var visitsByDay=
新字典(currentDate,newvisitsbyURL());
...
//内部哈希映射
公共类VisitsByUrl
{
公共字典URL{get;set;}
公共访问BYURL()
{
URL=新字典();
}
公共无效添加(字符串url)
{
如果(url[url]!=null)
url[url]+=1;
其他的
添加(url,1);
}
}
您可以为具有以下类型遗嘱的每一天保留一个哈希:-
和一个长度为n的队列。每天都会有这些散列。此外,您还将存储单独的hash totalHits,这些hash totalHits将对所有这些进行求和
Class Stats {
queue< hash<url,hits> > completeStats;
hash<url,hits> totalStats;
public:-
int getNoOfTodayHits(url) {
return completeStats[n-1][url];
}
int getTotalStats(url) {
return totalStats[url];
}
void addAnotherDay() {
// before popping check if the length is n or not :)
hash<url,hits> lastStats = completeStats.pop();
hash<url,hits> todayStats;
completeStats.push_back(todayStats);
// traverse through lastStats and decrease the value from total stats;
}
// etc.
};
类统计信息{
队列完成测试;
散列totalStats;
公众:-
int getNoOfTodayHits(url){
返回完整测试集[n-1][url];
}
int getTotalStats(url){
返回totalStats[url];
}
void addAnotherDay(){
//弹出前检查长度是否为n:)
hash lastStats=completeStats.pop();
散列今日统计数据;
完成测试。推回(今天的统计);
//遍历lastStats并从total stats中减少值;
}
//等等。
};
我们可以结合使用堆栈和哈希映射
我们可以创建一个URL和时间戳的对象,然后将其推送到堆栈上。
最近访问的Url将位于顶部
我们可以使用时间戳结合URL来创建一个键,该键映射到访问的URL的数量
为了按时间顺序显示访问量最大的页面,我们可以弹出堆栈,创建一个键并获取与Url关联的计数。在显示时对它们进行排序
时间复杂度:O(n)+排序时间(取决于访问的页面数量)我的想法也是一样的。这听起来是一个有效的解决方案。谢谢你的帮助!这与Karthik的期望背道而驰,没有考虑到他声明的功能需求——只有一个,而且不太现实,但是:“它必须先显示当天访问量最大的页面,然后显示第二天访问量最大的页面,依此类推”。散列图不会被排序,而你的散列图会被键入URL——你将如何找到访问量最大的页面?蛮力迭代,对于散列映射,它通常比向量迭代慢。散列映射允许快速的日内更新,但是当N的数组/向量更紧凑、更快时,为什么要使用外部散列映射呢?@Tony:我没说这是唯一的解决方案。对于完美主义类型的开发人员来说,它可能不够成熟/复杂/高效。谢谢你的否决票。有趣的解决方案,非常好。非常感谢。您选择使用哈希表队列而不是哈希表的哈希。你选择这个有什么特别的原因吗??我假设您在搜索统计数据时必须扫描整个队列并给出日期。你的想法是什么?我不需要在hash中处理键的日期:)Pop Push works:P
Class Stats {
queue< hash<url,hits> > completeStats;
hash<url,hits> totalStats;
public:-
int getNoOfTodayHits(url) {
return completeStats[n-1][url];
}
int getTotalStats(url) {
return totalStats[url];
}
void addAnotherDay() {
// before popping check if the length is n or not :)
hash<url,hits> lastStats = completeStats.pop();
hash<url,hits> todayStats;
completeStats.push_back(todayStats);
// traverse through lastStats and decrease the value from total stats;
}
// etc.
};