#include <stdio.h>
#include <stdbool.h>
#include <limits.h>
#include <stdlib.h>
typedef struct Frame
{
int pageId;
int visitNum;
int accessTime;
} Frame;
// 按照访问时间先后升序
int CompareByTime(const void *a, const void *b)
{
return ((Frame *)a)->accessTime - ((Frame *)b)->accessTime;
}
// 优先选择访问次数最少的 如果有多个 则选择最久未访问的
int CompareByVisitNumAndTime(const void *a, const void *b)
{
Frame *frameA = (Frame *)a;
Frame *frameB = (Frame *)b;
int visitNumA = frameA->visitNum;
int visitNumB = frameB->visitNum;
if (visitNumA == visitNumB)
{
return frameA->accessTime - frameB->accessTime;
}
else
{
return visitNumA - visitNumB;
}
}
int Solution(int frameNum, int windowSize, int pages[], int pagesSize)
{
// 初始化
Frame frames[frameNum];
int replaceCount = 0;
int time = 0;
int frameSize = 0;
for (int i = 0; i < frameNum; i++)
{
frames[i].pageId = -1;
frames[i].visitNum = -1;
frames[i].accessTime = -1;
}
// 遍历pages
for (size_t i = 0; i < pagesSize; i++)
{
// 是否命中
printf("The Current PageId is:%d\n", pages[i]);
bool found = false;
time++;
for (size_t j = 0; j < frameNum; j++)
{
if (frames[j].pageId == pages[i])
{
// 增加访问次数和刷新时间
frames[j].accessTime = time;
frames[j].visitNum++;
found = true;
break;
}
}
// 若命中 跳过这个
if (found)
{
continue;
}
// 若未命中 需要调到内存中
// 判断是否存在空间
// 存在空间
if (frameSize < frameNum)
{
for (size_t j = 0; j < frameNum; j++)
{
if (frames[j].pageId == -1)
{
// 调出到页框
frames[j].pageId = pages[i];
frames[j].visitNum = 1;
frames[j].accessTime = time;
frameSize++;
break;
}
}
}
else
{
// 页面置换
// 先按照访问时间先后,选择前windowsSize的作为候选
// 先复制一份
replaceCount++;
Frame tempFrames[frameNum];
for (size_t m = 0; m < frameNum; m++)
{
tempFrames[m].pageId = frames[m].pageId;
tempFrames[m].visitNum = frames[m].visitNum;
tempFrames[m].accessTime = frames[m].accessTime;
}
// 按照时间先后排序
qsort(tempFrames, frameNum, sizeof(Frame), CompareByTime);
// 获取前window个
Frame windowFrames[windowSize];
for (size_t m = 0; m < windowSize; m++)
{
windowFrames[m].pageId = tempFrames[m].pageId;
windowFrames[m].visitNum = tempFrames[m].visitNum;
windowFrames[m].accessTime = tempFrames[m].accessTime;
}
// 选择优先次数最少 若多个则最久未访问
qsort(windowFrames, windowSize, sizeof(Frame), CompareByVisitNumAndTime);
// 选择第一个置换
int replaceId = windowFrames[0].pageId;
printf("The replaceId is %d\n", replaceId);
for (size_t m = 0; m < frameNum; m++)
{
if (frames[m].pageId == replaceId)
{
frames[m].pageId = pages[i];
frames[m].visitNum = 1;
frames[m].accessTime = time;
break;
}
}
}
}
return replaceCount;
}
int main()
{
int frameNum = 4;
int windowSize = 3;
int pages[] = {21, 22, 23, 24, 25, 21, 22, 23, 24, 26};
int pages_size = sizeof(pages) / sizeof(pages[0]);
int result = Solution(frameNum, windowSize, pages, pages_size);
printf("%d\n", result); // 输出 4
return 0;
}
/*
注意事项:
1. qsort一定不能忘记 qsort(arr, sizeof(arr)/sizeof(arr[0]), sizeof(arr[0]),CompareFunction);
2. 注意索引的细节
3. 注意重要变量 比如frameSize一定要记得++
*/