#P3050. 热点网站统计(100分)
-
1000ms
Tried: 237
Accepted: 59
Difficulty: 3
所属公司 :
华为od
-
算法标签>哈希表
热点网站统计(100分)
题目描述
公司有一个路由器统计页面,要求动态统计公司内访问量最多的 URL 的 Top N。输入由 URL 和数字 N 组成,URL 表示访问的网页,数字 N 表示需要输出访问次数最高的 Top N 个 URL,输出按照访问次数降序排列,如果访问次数相同,则按字典序升序排列。
输入描述
- 每一行输入是一个
URL或一个正整数N。 - 如果是
URL,表示网页访问记录;如果是N,表示当前要输出的Top N个URL。 - 输入约束:
- 总访问网页数小于
5000个,单个网页访问次数小于65535次; - 网页
URL仅由字母、数字和.组成,长度不超过127字节; - 数字
N小于等于10,且小于当前总访问网页数。
- 总访问网页数小于
输出描述
- 每次输出按之前所有输入统计的
Top N访问量最高的URL,用逗号分隔。 - 如果有多个
URL访问次数相同,按字典序升序排列。
题解思路
- 数据结构:使用
unordered_map来存储URL的访问次数。 - 优先队列:用自定义结构体
URLRecord和priority_queue获取访问次数最高的N个URL。priority_queue结合自定义比较规则,使URL按访问次数降序排列,若访问次数相同则按字典序升序排列。 - 处理输入:
- 若输入为
URL,更新其在unordered_map中的访问次数。 - 若输入为数字
N,使用优先队列对所有URL统计访问次数,并提取前N个结果输出。
- 若输入为
复杂度分析
- 时间复杂度:处理每个
URL插入到unordered_map为 O(1),每次查询Top N需要遍历unordered_map并插入priority_queue,因此为 O(M log M)(其中M为unordered_map中的元素数量)。 - 空间复杂度:优先队列和哈希表的空间总复杂度为 O(M)。
代码实现
C++
#include <bits/stdc++.h>
using namespace std;
// 自定义结构,用于在优先队列中存储URL和访问次数
struct URLRecord {
string url;
int count;
// 自定义比较规则
bool operator<(const URLRecord& other) const {
if (count == other.count) {
return url > other.url; // 访问次数相同按字典序升序排列
}
return count < other.count; // 访问次数降序排列
}
};
// 统计访问次数的哈希表
unordered_map<string, int> urlCount;
void processInput(const string& input) {
// 判断输入是否为数字
if (isdigit(input[0])) {
int N = stoi(input);
// 使用优先队列获取前N个访问次数最多的URL
priority_queue<URLRecord> pq;
for (const auto& entry : urlCount) {
pq.push({entry.first, entry.second});
}
vector<string> topN;
for (int i = 0; i < N && !pq.empty(); ++i) {
topN.push_back(pq.top().url);
pq.pop();
}
// 输出结果
for (int i = 0; i < topN.size(); ++i) {
if (i > 0) cout << ",";
cout << topN[i];
}
cout << endl;
} else {
// 如果是URL,将其计数增加
urlCount[input]++;
}
}
int main() {
string line;
while (cin >> line) {
processInput(line);
}
return 0;
}
Python
import heapq
from collections import defaultdict
# 统计访问次数的字典
url_count = defaultdict(int)
def process_input(input_line):
if input_line.isdigit():
N = int(input_line)
# 使用堆来获取前N个访问次数最多的URL
pq = []
for url, count in url_count.items():
heapq.heappush(pq, (-count, url)) # 使用负数实现最大堆
top_n = []
for _ in range(N):
top_n.append(heapq.heappop(pq)[1])
print(",".join(top_n))
else:
# 如果是URL,将其计数增加
url_count[input_line] += 1
# 模拟输入
while True:
try:
line = input().strip()
process_input(line)
except EOFError:
break
Java
import java.util.*;
public class Main {
static Map<String, Integer> urlCount = new HashMap<>();
public static void processInput(String input) {
if (Character.isDigit(input.charAt(0))) {
int N = Integer.parseInt(input);
// 使用优先队列获取前N个访问次数最多的URL
PriorityQueue<URLRecord> pq = new PriorityQueue<>();
for (Map.Entry<String, Integer> entry : urlCount.entrySet()) {
pq.add(new URLRecord(entry.getKey(), entry.getValue()));
}
List<String> topN = new ArrayList<>();
int cnt = N;
while (cnt > 0 && !pq.isEmpty()) {
topN.add(pq.poll().url);
cnt --;
}
System.out.println(String.join(",", topN));
} else {
// 如果是URL,将其计数增加
urlCount.put(input, urlCount.getOrDefault(input, 0) + 1);
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()) {
String line = scanner.nextLine().trim();
processInput(line);
}
}
}
class URLRecord implements Comparable<URLRecord> {
String url;
int count;
public URLRecord(String url, int count) {
this.url = url;
this.count = count;
}
@Override
public int compareTo(URLRecord other) {
if (this.count == other.count) {
return this.url.compareTo(other.url); // 访问次数相同按字典序升序排列
}
return Integer.compare(other.count, this.count); // 访问次数降序排列
}
}
题目描述
企业路由器的统计页面,有一个功能需要动态统计公司访问最多的网页 URL top N 。
请设计一个算法,可以高效动态统计 Top N的页面。
输入描述
每一行都是一个 URL 或一个数字,如果是 URL ,代表一段时间内的网页访问; 如果是一个数字 N ,代表本次需要输出的Top N个 URL。
输入约束:
1、总访问网页数量小于 5000 个,单网页访问次数小于 65535 次;
2、网页 URL 仅由字母,数字和点分隔符组成,且长度小于等于 127 字节;
3、数字是正整数,小于等于 10 且小于当前总访问网页数;
输出描述
每行输入要对应一行输出,输出按访问次数排序的前 N 个 URL ,用逗号分隔。
输出要求:
1、每次输出要统计之前所有输入,不仅是本次输入;
2、如果有访问次数相等的 URL ,按 URL 的字符串字典序升序排列,输出排序靠前的 URL ;
样例1
输入
news.qq.com
news.sina.com.cn
news.qq.com
news.qq.com
game.163.com
game.163.com
www.huawei.com
www.cctv.com
3
www.huawei.com
www.cctv.com
www.huawei.com
www.cctv.com
www.huawei.com
www.cctv.com
www.huawei.com
www.cctv.com
www.huawei.com
3
输出
news.qq.com,game.163.com,news.sina.com.cn
www.huawei.com,www.cctv.com,news.qq.com
样例2
输入
news.qq.com
www.cctv.com
1
www.huawei.com
www.huawei.com
2
3
输出
news.qq.com
www.huawei.com,news.qq.com
www.huawei.com,news.qq.com,www.cctv.com