(B卷,100分)- 热点网站统计(Java & JS & Python)

题目描述

企业路由器的统计页面,有一个功能需要动态统计公司访问最多的网页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;

用例

输入 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
说明
输入 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
说明

题目解析

本题需要注意:“每次输出要统计之前所有输入,不仅是本次输入”。

这句话,可以看第一个用例的第二行输出,其中news.qq.com的输出就取决于上面这句话。

另外,还有这句话:“总访问网页数量小于5000个,单网页访问次数小于65535次;

也就说,最多有不超过5000 * 65535条访问URL记录,这个规模,我们需要尽可能地优化代码时间复杂度到O(1)左右,特别是“每次输出要统计之前所有输入,不仅是本次输入”,我们最好创建缓存表,而不是重新统计。

其余地就感觉没什么需要注意的了,都是逻辑实现了。


2023.08.28

根据考友反馈,本题输入截止条件不能使用空行判断,可以直接死循环获取

JS算法源码

const rl = require("readline").createInterface({ input: process.stdin });
var iter = rl[Symbol.asyncIterator]();
const readline = async () => (await iter.next()).value;

void (async function () {
  const cache = {};

  while (true) {
    const line = await readline();

    if (/^d+$/.test(line)) {
      console.log(sortURL(parseInt(line)));
    } else {
      cache[line] ? cache[line]++ : (cache[line] = 1);
    }
  }

  function sortURL(n) {
    return Object.entries(cache)
      .sort((a, b) => {
        // entry[0]代表key,即url
        // entry[1]代表val, 即出现次数count
        const res = b[1] - a[1];
        return res == 0 ? (a[0] > b[0] ? 1 : -1) : res;
      })
      .slice(0, n)
      .map((entry) => entry[0])
      .join(",");
  }
})();

Java算法源码

import java.util.HashMap;
import java.util.Objects;
import java.util.Scanner;
import java.util.StringJoiner;
import java.util.regex.Pattern;

public class Main {
  // 改正则用于判断一个字符串是否为正整数
  static Pattern reg = Pattern.compile("^\d+$");

  // cache记录每个url出现次数
  static HashMap<String, Integer> cache = new HashMap<>();

  public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);

    while (sc.hasNextLine()) {
      String tmp = sc.nextLine();

      if (reg.matcher(tmp).find()) {
        // 如果输入的是正整数
        System.out.println(sortURL(Integer.parseInt(tmp)));
      } else {
        // 输入的是url
        cache.put(tmp, cache.getOrDefault(tmp, 0) + 1);
      }
    }
  }

  public static String sortURL(int n) {
    StringJoiner sj = new StringJoiner(",");

    cache.entrySet().stream()
        .sorted(
            (a, b) ->
                Objects.equals(a.getValue(), b.getValue())
                    ? a.getKey().compareTo(b.getKey())
                    : b.getValue() - a.getValue())
        .limit(n)
        .map(ele -> ele.getKey())
        .forEach(url -> sj.add(url));

    return sj.toString();
  }
}

Python算法源码

# 输入获取
cache = {}  # 记录每个url出现的次数
ans = []  # 记录题解


def sortURL(n):
    urlCount = list(cache.items())
    urlCount.sort(key=lambda x: (-x[1], x[0]))

    return ",".join(map(lambda x: x[0], urlCount[:n]))


while True:
    tmp = input()

    if tmp.isnumeric():  # 如果输入的是数字,则需要对前面输入的url进行排序统计
        print(sortURL(int(tmp)))
    else:
        if cache.get(tmp) is None:
            cache[tmp] = 1
        else:
            cache[tmp] += 1

免责声明:

1、IT资源小站为非营利性网站,全站所有资料仅供网友个人学习使用,禁止商用
2、本站所有文档、视频、书籍等资料均由网友分享,本站只负责收集不承担任何技术及版权问题
3、如本帖侵犯到任何版权问题,请立即告知本站,本站将及时予与删除下载链接并致以最深的歉意
4、本帖部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责
5、一经注册为本站会员,一律视为同意网站规定,本站管理员及版主有权禁止违规用户
6、其他单位或个人使用、转载或引用本文时必须同时征得该帖子作者和IT资源小站的同意
7、IT资源小站管理员和版主有权不事先通知发贴者而删除本文

0

评论0

站点公告

没有账号?注册  忘记密码?