(C卷,100分)- 内存冷热标记(Java & JS & Python & C)

题目描述

现代计算机系统中通常存在多级的存储设备,针对海量 workload 的优化的一种思路是将热点内存页优先放到快速存储层级,这就需要对内存页进行冷热标记。

一种典型的方案是基于内存页的访问频次进行标记,如果统计窗口内访问次数大于等于设定阈值,则认为是热内存页,否则是冷内存页。

对于统计窗口内跟踪到的访存序列和阈值,现在需要实现基于频次的冷热标记。内存页使用页框号作为标识。

输入描述

第一行输入为 N,表示访存序列的记录条数,0 < N ≤ 10000。

第二行为访存序列,空格分隔的 N 个内存页框号,页面号范围 0 ~ 65535,同一个页框号可能重复出现,出现的次数即为对应框号的频次。

第三行为热内存的频次阈值 T,正整数范围 1 ≤ T ≤ 10000。

输出描述

第一行输出标记为热内存的内存页个数,如果没有被标记的热内存页,则输出 0 。

如果第一行 > 0,则接下来按照访问频次降序输出内存页框号,一行一个,频次一样的页框号,页框号小的排前面。

用例

输入 10
1 2 1 2 1 2 1 2 1 2
5
输出 2
1
2
说明 内存页1和内存页2均被访问了5次,达到了阈值5,因此热内存页有2个。内存页1和内存页2的访问频次相等,页框号小的排前面。
输入 5
1 2 3 4 5
3
输出 0
说明 访存跟踪里面访存频次没有超过3的,因此热内存个数为0。

题目解析

简单的多条件排序问题。

具体逻辑请看代码实现。

JavaScript算法源码

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

void (async function () {
  const n = parseInt(await readline());

  const seqs = (await readline()).split(" ").map(Number);

  const cnts = {};
  for (let num of seqs) {
    cnts[num] = (cnts[num] ?? 0) + 1; // ?? 是高级语法,如果cnts[num]为null或者undefined时,返回0,实际牛客环境可能不支持
  }

  const threshold = parseInt(await readline());

  // Object.entries返回的是数组,返回值数组的元素也是一个数组[key, value],其中key,value就是对象的键值对
  const entries = Object.entries(cnts).filter((a) => a[1] >= threshold);

  console.log(entries.length);

  // entries元素数组的索引0是对象key,索引1是对象val
  entries
    .sort((a, b) => (a[1] != b[1] ? b[1] - a[1] : a[0] - b[0]))
    .forEach((a) => console.log(a[0]));
})();

Java算法源码

import java.util.HashMap;
import java.util.Scanner;

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

    int n = sc.nextInt();

    HashMap<Integer, Integer> cnts = new HashMap<>();
    for (int i = 0; i < n; i++) {
      int num = sc.nextInt();
      cnts.put(num, cnts.getOrDefault(num, 0) + 1);
    }

    int threshold = sc.nextInt();

    cnts.keySet().removeIf(num -> cnts.get(num) < threshold);

    System.out.println(cnts.size());

    cnts.entrySet().stream()
        .sorted(
            (a, b) ->
                a.getValue() - b.getValue() != 0
                    ? b.getValue() - a.getValue()
                    : a.getKey() - b.getKey())
        .forEach(a -> System.out.println(a.getKey()));
  }
}

Python算法源码

# 输入获取
n = int(input())
seqs = list(map(int, input().split()))
threshold = int(input())

# 统计各个内存页框号出现的次数
cnts = {}
for num in seqs:
    cnts.setdefault(num, 0)
    cnts[num] += 1

# 过滤出现次数达到阈值的内存页,即热内存页数量
items = list(filter(lambda x: x[1] >= threshold, cnts.items()))

# 打印热内存页数量
print(len(items))

# 如果存在热内存页
if len(items) > 0:
    # 那么优先按照访问频次降序,如果访问频次相同,则再按页框号升序,items中记录元素是[页框号, 访问频次]
    items.sort(key=lambda x: (-x[1], x[0]))

    for num, _ in items:
        print(num)

C算法源码

#include <stdio.h>
#include <stdlib.h>

#define MAX_SIZE 10000

typedef struct Mem {
    int num;
    int count;
} Mem;

int cmp(const void *a, const void *b) {
    Mem *A = *((Mem **) a);
    Mem *B = *((Mem **) b);

    if (A->count != B->count) {
        return B->count - A->count;
    } else {
        return A->num - B->num;
    }
}

int main() {
    int n;
    scanf("%d", &n);

    Mem *mem[MAX_SIZE];
    int mem_size = 0;

    for (int i = 0; i < n; i++) {
        int num;
        scanf("%d", &num);

        int j = 0;
        for (; j < mem_size; j++) {
            if (mem[j]->num == num) {
                mem[j]->count++;
                break;
            }
        }

        if(j < mem_size) continue;

        mem[mem_size] = (Mem *) malloc(sizeof(Mem));
        mem[mem_size]->num = num;
        mem[mem_size]->count = 1;

        mem_size++;
    }

    int threshold;
    scanf("%d", &threshold);

    qsort(mem, mem_size, sizeof(Mem *), cmp);

    int hot_mem_size = mem_size;
    for (int i = 0; i < mem_size; i++) {
        if (mem[i]->count < threshold) {
            hot_mem_size = i;
            break;
        }
    }

    printf("%dn", hot_mem_size);

    for (int i = 0; i < hot_mem_size; i++) {
        printf("%dn", mem[i]->num);
    }

    return 0;
}

免责声明:

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

0

评论0

站点公告

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