【NC16589】机器翻译

题目

机器翻译

先进先出 ( F I F O ) (FIFO) (FIFO) 的内存置换算法、队列、哈希表

思路

题目很直观,有一个大小受限的内存,如果内存没装满就装,装满了则将最先装入的那一块换掉,再装新的。

这是一种先进先出 ( F I F O ) (FIFO) (FIFO) 的模式,使用队列来模拟再合适不过了。

不过题目又提到在装入内存之前还要先判断一下内存中是否已经存在,如果存在的话就忽略,否则再装。

如果使用队列的话,判断某个元素是否在队列中需要的时间复杂度为 O ( n ) O(n) O(n),这显然不是一种好的算法,所以引入哈希集合来进行优化。

总体思路就是:

  1. 设置一个计数值,初始为 0
  2. 读入一个元素,判断其是否在哈希集合中(这个操作的时间复杂度很低,可近似看作 O ( 1 ) O(1) O(1)
    2.1 如果在,则忽略
    2.2 如果不在,则将其加入哈希集合和队列:如果队列不满,则直接加入;如果队列已满,则先将队首元素移出哈希集合,然后再将队首元素出队,然后再将当前元素入队,并将计数值加一
  3. 重复这个操作直到数据读取完毕。
  4. 输出计数值

注意

队列和哈希集合可以使用 STL 封装的。但既然是学习,何不自己手搓呢?正好练习一下循环队列。至于哈希集合,这道题的数据很小,直接用数组模拟即可(数据如果很大的话使用库封装的哈希集合比自己手搓的好用)

代码

// 纯C语言
#include <stdio.h>
#define N 1005
#define M 105

// 注意C语言中全局变量是会自动初始化为0的
int q[M], h, r;  // 队列及其头尾指针,初始 h = r = 0
int set[N];      // 哈希集合,初始全为0,表示没有元素

int main(void) {
    int n = 0, m = 0, x = 0, ans = 0;
    scanf("%d%d", &m, &n);
    while (n--) {
        scanf("%d", &x);
        if (!set[x]) {
            // 如果哈希表中不存在,则说明要到外存中找,答案加一
            ans++;
            // 加入队列和哈希表
            set[x] = 1;
            if ((r + 1) % (m + 1) == h) {
                // 如果队列是满的,则要先将队首元素出队
                // 不过在这之前要先将哈希表中的元素删除
                set[q[h++]] = 0;
                // 循环
                if (h == m + 1) h = 0;
            }
            // 不管队列是不是满的,都要将当前元素入队
            // 新元素加入队列
            q[r++] = x;
            // 循环
            if (r == m + 1) r = 0;
        }
    }
    printf("%d\n", ans);
    return 0;
}
  • 13
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

木又可可

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值