当前位置: 首页> 文旅> 旅游 > 企业标准信息公共服务平台_广告代理商是什么_什么软件可以优化关键词_北京网站推广营销策划

企业标准信息公共服务平台_广告代理商是什么_什么软件可以优化关键词_北京网站推广营销策划

时间:2025/7/13 9:21:49来源:https://blog.csdn.net/zxjiaya/article/details/145835871 浏览次数:0次
企业标准信息公共服务平台_广告代理商是什么_什么软件可以优化关键词_北京网站推广营销策划

LFU缓存算法的实现

    • 代码解析
      • 代码结构和实现原理
      • 函数定义
      • 插入操作
      • 查询操作
    • 代码注释
      • 变量初始化
      • 插入操作逻辑
      • 查询操作逻辑
    • 总结

参考下列结构图和视频

在这里插入图片描述

代码解析

#include <stdio.h>
#include <stdlib.h>/*** 实现一个简单的 LFU(Least Frequently Used)缓存算法。** @param operators 二维数组,表示操作指令。* @param operatorsRowLen 操作数组的行数。* @param operatorsColLen 操作数组的列数。* @param k 缓存的容量。* @param returnSize 返回数组的行数。* @return 返回一个一维数组,表示每次操作的结果。*/
int* LFU(int** operators, int operatorsRowLen, int* operatorsColLen, int k,int* returnSize) {// 分配返回数组,大小为操作数组的行数int* a = (int*)malloc(sizeof(int) * operatorsRowLen);// 分配缓存数组,大小为 k,每个缓存项包含 4 个字段int** t = (int**)malloc(sizeof(int*) * k);for (int i = 0; i < k; i++) {t[i] = (int*)malloc(sizeof(int) * 4);// 初始化缓存项:// t[i][0]:访问频率,初始为 0// t[i][1]:键值,初始为 0// t[i][2]:值,初始为 0// t[i][3]:时间戳,初始为 0t[i][0] = 0;t[i][1] = 0;t[i][2] = 0;t[i][3] = 0;}// 返回数组的当前长度int alen = 0;// 遍历操作数组for (int i = 0; i < operatorsRowLen; i++) {// 标记是否找到对应的键char set = 0;// 操作类型为 1,表示插入或更新键值对if (operators[i][0] == 1) {// 遍历缓存数组,查找是否存在相同的键for (int j = 0; j < k; j++) {if (t[j][1] == operators[i][1 ]){ // 找到相同的键// 更新键对应的值t[j][2] = operators[i][2];// 增加访问频率t[j][0]++;// 更新时间戳t[j][3] = i;// 标记找到set = 1;break;}}// 如果缓存中不存在该键if (set == 0) {// 初始化最小频率为一个较大的值int min = 10000;int p;  // 用于记录需要替换的缓存项索引// 遍历缓存数组,找到访问频率最小的项for (int j = 0; j < k; j++) {if (t[j][0] < min) {min = t[j][0];p = j;} else if (t[j][0] == min && t[j][3] < t[p][3]) {// 如果频率相同,比较戳时间,选择最早插入的项min = t[j][0];p = j;}}// 替换访问频率最小的缓存项t[p][1] = operators[i][1];  // 更新键t[p][2] = operators[i][2];  // 更新值t[p][0] = 1;                // 初始化访问频率为 1t[p][3] = i;                // 更新时间戳}} else {  // 操作类型为 2表示,查询键值// 遍历缓存数组,查找是否存在相同的键for (int j = 0; j < k; j++) {if (t[j][1] == operators[i][1]) {  // 找到相同的键// 将键对应的值添加到返回数组中a[alen++] = t[j][2];// 增加访问频率t[j][0]++;// 更新时间戳t[j][3] = i;// 标记找到set = 1;break;}}// 如果缓存中不存在该键if (set == 0) {// 将 -1 添加到返回数组中,表示查询失败a[alen++] = -1;}}}// 设置返回数组的大小*returnSize = alen;// 返回结果数组return a;
}

代码结构和实现原理

LFU缓存算法的核心思想是根据访问频率来决定缓存项的淘汰顺序。频率最低的缓存项最先被淘汰。

函数定义

int* LFU(int** operators, int operatorsRowLen, int* operatorsColLen, int k, int* returnSize) {int* a = (int*)malloc(sizeof(int) * operatorsRowLen);  // 用于存储每次操作的结果// 分配缓存数组,大小为 k,每个缓存项包含 4 个字段int** t = (int**)malloc(sizeof(int*) * k);for (int i = 0; i < k; i++) {t[i] = (int*)malloc(sizeof(int) * 4);t[i][0] = 0;  // 访问频率,初始为 0t[i][1] = 0;  // 键值,初始为 0t[i][2] = 0;  // 值,初始为 0t[i][3] = 0;  // 时间戳,初始为 0}int alen = 0;  // 返回数组的当前长度

变量说明:

  • a: 返回数组,用于存储每次操作的结果。
  • t: 缓存数组,大小为 k,每个缓存项有四个字段:
    1. t[i][0]: 访问频率(初始为 0)
    2. t[i][1]: 键值(初始为 0)
    3. t[i][2]: 值(初始为 0)
    4. t[i][3]: 时间戳(初始为 0)

插入操作

if (operators[i][0] == 1) {// 查找是否存在相同的键for (int j = 0; j < k; j++) {if (t[j][1] == operators[i][1]) {  // 找到相同的键t[j][2] = operators[i][2];  // 更新值t[j][0]++;  // 增加访问频率t[j][3] = i;  // 更新时间戳set = 1;  // 标记为已找到break;}}// 如果缓存中不存在该键if (set == 0) {int min = 10000;  // 初始化最小频率为一个较大的值int p;  // 用于记录需要替换的缓存项索引// 遍历缓存数组,找到访问频率最小的项for (int j = 0; j < k; j++) {if (t[j][0] < min) {min = t[j][0];p = j;} else if (t[j][0] == min && t[j][3] < t[p][3]) {// 如果频率相同,比较戳时间,选择最早插入的项min = t[j][0];p = j;}}// 替换访问频率最小的缓存项t[p][1] = operators[i][1];  // 更新键t[p][2] = operators[i][2];  // 更新值t[p][0] = 1;  // 初始化访问频率为 1t[p][3] = i;  // 更新时间戳}
}

插入操作步骤:

  • 查找缓存:遍历缓存数组,如果找到对应的键,更新其值、访问频率和时间戳。
  • 替换缓存:如果缓存中没有对应的键,找到访问频率最小的缓存项进行替换。若频率相同,则替换最早插入的缓存项。

查询操作

else {  // 操作类型为 2表示,查询键值for (int j = 0; j < k; j++) {if (t[j][1] == operators[i][1]) {  // 找到相同的键a[alen++] = t[j][2];  // 将键对应的值添加到返回数组中t[j][0]++;  // 增加访问频率t[j][3] = i;  // 更新时间戳set = 1;  // 标记为已找到break;}}// 如果缓存中不存在该键if (set == 0) {a[alen++] = -1;  // 将 -1 添加到返回数组中,表示查询失败}
}

查询操作步骤:

  • 查找缓存:遍历缓存数组,如果找到对应的键,返回其值,并更新其访问频率和时间戳。
  • 未找到键:如果缓存中没有找到对应的键,返回 -1 表示查询失败。

代码注释

变量初始化

// 分配返回数组,大小为操作数组的行数
int* a = (int*)malloc(sizeof(int) * operatorsRowLen);// 分配缓存数组,大小为 k,每个缓存项包含 4 个字段
int** t = (int**)malloc(sizeof(int*) * k);
for (int i = 0; i < k; i++) {t[i] = (int*)malloc(sizeof(int) * 4);t[i][0] = 0;  // 访问频率,初始为 0t[i][1] = 0;  // 键值,初始为 0t[i][2] = 0;  // 值,初始为 0t[i][3] = 0;  // 时间戳,初始为 0
}
  • a 数组用于存储每次操作的返回结果。
  • t 是缓存数组,存储缓存项的详细信息,包括访问频率、键值、值和时间戳。

插入操作逻辑

if (operators[i][0] == 1) {// 遍历缓存数组,查找是否存在相同的键for (int j = 0; j < k; j++) {if (t[j][1] == operators[i][1]) {  // 找到相同的键t[j][2] = operators[i][2];  // 更新值t[j][0]++;  // 增加访问频率t[j][3] = i;  // 更新时间戳set = 1;  // 标记为已找到break;}}// 如果缓存中不存在该键if (set == 0) {int min = 10000;  // 初始化最小频率为一个较大的值int p;  // 用于记录需要替换的缓存项索引// 找到访问频率最小的缓存项for (int j = 0; j < k; j++) {if (t[j][0] < min) {min = t[j][0];p = j;} else if (t[j][0] == min && t[j][3] < t[p][3]) {min = t[j][0];p = j;}}// 替换缓存项t[p][1] = operators[i][1];  // 更新键t[p][2] = operators[i][2];  // 更新值t[p][0] = 1;  // 访问频率设为 1t[p][3] = i;  // 更新时间戳}
}

查询操作逻辑

else {  // 操作类型为 2表示,查询键值for (int j = 0; j < k; j++) {if (t[j][1] == operators[i][1]) {  // 找到相同的键a[alen++] = t[j][2];  // 返回对应的值t[j][0]++;  // 增加访问频率t[j][3] = i;  // 更新时间戳set = 1;  // 标记为已找到break;}}// 如果缓存中没有该键,返回 -1if (set == 0) {a[alen++] = -1;  // 查询失败}
}

总结

LFU缓存算法的核心是维护缓存项的访问频率并使用最小频率来决定淘汰策略。通过此算法,我们可以有效地管理缓存,保证最常用的缓存项不会被替换。这题还是比LRU简单点。而且采用数组,没有完全使用链表,简单很多。不想是LRU一个系统,这题本质上是一个函数,一个里面套着俩函数。插入和查找。

关键字:企业标准信息公共服务平台_广告代理商是什么_什么软件可以优化关键词_北京网站推广营销策划

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: