项目的结构
源码已放在网盘,需要代码自取
链接:https://pan.baidu.com/s/1yn7XuEqMbTTgTvFnlvxKKg
提取码:1234
复制这段内容后打开百度网盘手机App,操作更方便哦
job工作类头文件
#ifndef JOB_H
#define JOB_H
#include <iostream>
#include <vector>
using namespace std;
class Job
{
public:
Job();
/*
父类的一些函数,子类如果想要在自己的构造函数中初始化某些内容,
可以声明来使用:如子类FIFO:
FIFO:FIFO():Job() */
void readData(string src);//读写文件函数
void writeData(string dest);
void show();
bool isContain(int page);
//每个子类中都有不同的execute和查页面的实现,所以要在父类中定义成虚函数,子类继承实现
virtual void execute() = 0;
virtual int SolveJobPage(int curLocation) = 0;
protected:
//定义数据结构
int miss;//记录缺页次数
int memerySize;//可用的物理块个数
int curMemorySize; //当前调入主存中的页面个数
vector<int> records;//作业页面集
vector<int> memory;//内存页面集
vector<vector<int>> memroyRecords;
vector<bool> contain;//缺页标识
private:
};
#endif // JOB_H
四个子类的头文件基本类似,继承job的头文件
算法的具体实现和job类的具体实现
job
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <ostream>
#include "Job.h"
Job::Job()
{
//ctor构造类型初始化
memerySize = 3;//定义物理块个数3个
curMemorySize = 0;//当前调入主存的页面个数初始化为0
miss = 0 ;//缺页次数初始化0
memory = vector<int>(3,0);//内存页面集初始化
}
/*Job::Job(){
memory = vector<int>(3,0);
memerySize = 3;
curMemorySize = 0;
miss = 0;
}
*/
void Job::readData(string source)//实现Job类里的读文件函数
{
ifstream infile;//文件以输入方式打开,文件数据输入到内存
infile.open(source.c_str());/*string类对象的成员函数c_str()这里c_str() 以 char* 形式传回 string 内含字符串
当需要打开一个由用户自己输入文件名的文件时,可以这样写:ifstream in(st.c_str());。
其中st是string类型,存放的即为用户输入的文件名。*/
string record;
while(infile >> record){
records.push_back(atoi(record.c_str()));
//push_back() 在Vector最后添加一个元素
//atoi是cstring字符处理函数,把数字字符串转换成int输出
//atoi()的参数是char,对于一个字符串str须调用 c_str()把这个string转换成 const char*类型的
}
}
void Job::writeData(string destination) //实现Job类里的写文件函数
{
ofstream outfile;
outfile.open(destination);
//文件以输出方式打开(内存数据输出到文件)
for(int i=0; i<records.size(); i++)//打印读出来的页面序列
{
if(i == 0){
outfile << "页面序列为" << '\t' << records[i] << "\t";// \t后移一个制表位置
}else{
outfile << records[i] << "\t";
}
}
outfile<<endl;
for(int i=0; i < memroyRecords[0].size(); i++)//打印每一个物理块随主存调入页面的改变序列
{
for(int j=0; j<memroyRecords.size();j++)
{
if(j == 0){
outfile<<"第"<< i+1<<"物理块"<< '\t' << memroyRecords[j][i] <<"\t";
}else{
outfile << memroyRecords[j][i]<<"\t";
}
}
outfile<<endl;
}
for(int i=0; i<records.size(); i++)//打印缺页情况
{
if(i == 0){
outfile << "是否缺页" << '\t';
}
if(!contain[i]){
outfile <<" \t";
}else{
outfile << "缺\t";
}
}
outfile<<endl;
outfile<<endl;
outfile << "缺页率:" << miss << "\\" << records.size()<<endl; // \\转义的除号
}
void Job::show()
{
for(int i=0; i<records.size(); i++)//打印读出来的页面序列
{
if(i == 0){
cout << "页面序列为" << '\t' << records[i] << "\t";// \t后移一个制表位置
}else{
cout << records[i] << "\t";
}
}
cout<<endl;
for(int i=0; i < memroyRecords[0].size(); i++)//打印每一个物理块随主存调入页面的改变序列
{
for(int j=0; j<memroyRecords.size();j++)
{
if(j == 0){
cout<<"第"<< i+1<<"物理块"<< '\t' << memroyRecords[j][i] <<"\t";
}else{
cout << memroyRecords[j][i]<<"\t";
}
}
cout<<endl;
}
for(int i=0; i<records.size(); i++)//打印缺页情况
{
if(i == 0){
cout << "是否缺页" << '\t';
}
if(!contain[i]){
cout <<" \t";
}else{
cout << "缺\t";
}
}
cout<<endl;
cout<< "缺页率:" << miss << "\\" << records.size()<<endl; // \\转义的除号
}
bool Job::isContain(int page)//判断命中
{
int flag = false;
//页面号命中物理块号中的序列就是不缺页
for(int i=0; i<memerySize; i++){
if(page == memory[i]){
flag = true;
break;
}
}
return flag;
}
FIFO
#include "FIFO.h"
#include <iostream>
#include <fstream>
#include <ostream>
#include <cstdlib>
#include <algorithm>
#include <cstring>
using namespace std;
void FIFO::execute()//子类实现自己的执行函数
{
readData("./input/data.txt");
//读入数据
bool flag1 =false;//设置一个缺页标志位初始化位缺页
int curPage;//当前页面
for(int i=0; i<records.size(); i++)
{
curPage = records[i];
flag1 =false;
if(!isContain(curPage))//这里用了父类中的布尔判断
{
if (curMemorySize < memerySize)
{
memory[curMemorySize++] = records[i];
flag1 = true;
} else {
int pageIndex =SolveJobPage(i);
memory[pageIndex] = curPage;
flag1 = true;
}
}
contain.push_back(flag1);//加入缺页的标志位
if(flag1){
miss++;
order.push(curPage);
}
memroyRecords.push_back(memory);
}
writeData("./output/FIFO.txt"); //写出数据到文件
}
int FIFO::SolveJobPage(int curLocation){
int tmp = order.front();
order.pop();
for(int i=0; i<memerySize; i++){
if(tmp == memory[i]){
return i;
}
}
}
LFU
#include "LFU.h"
#include <fstream>
#include <ostream>
#include <cstdlib>
#include <cstring>
//LFU(Least Frequently Used ,最近最少使用算法
void LFU::execute()
{//逻辑也基本一致,区别在于页面的换入换出函数那里
readData("./input/data.txt");
//读入数据
bool flag2=false;//设置一个缺页标志位初始化位缺页
int curPage;//当前页面
for(int i=0; i<records.size(); i++)
{
curPage = records[i];
flag2 =false;
if(!isContain(curPage))//
{
if (curMemorySize < memerySize)
{
memory[curMemorySize++] = records[i];
flag2 = true;
} else {
int pageIndex =SolveJobPage(i);
memory[pageIndex] = curPage;
flag2 = true;
}
}
contain.push_back(flag2);//加入缺页的标志
if(flag2){
miss++;
}
memroyRecords.push_back(memory);
}
writeData("./output/LFU.txt"); //写出数据到文件
}
int LFU::SolveJobPage(int curLocation)
{
vector<int> num(memerySize,0);//其实就是3个整型元素的向量,每一个的初始值定义为0
int max = 0;
int index = 0;
for(int i=0; i<memerySize; i++)
{
for(int j=0; j<curLocation; j++){
if(memory[i] == records[j]){
num[i]++;
}
}
}
for(int i=0; i < memerySize; i++){
if(max > num[i]){
index = i;
max = num[i];
}
}
return index;
}
LRU
#include "LRU.h"
#include <fstream>
#include <ostream>
#include <cstdlib>
#include <cstring>
//LRU(The Least Recently Used,最近最久未使用算法
void LRU::execute()
{//这个函数和前面的逻辑也基本一致,区别在于页面的换入换出函数那里
readData("./input/data.txt");
//读入数据
bool flag2=false;//设置一个缺页标志位初始化位缺页
int curPage;//当前页面
for(int i=0; i<records.size(); i++)
{
curPage = records[i];
flag2 =false;
if(!isContain(curPage))//
{
if (curMemorySize < memerySize)
{
memory[curMemorySize++] = records[i];
flag2 = true;
} else {
int pageIndex =SolveJobPage(i);
memory[pageIndex] = curPage;
flag2 = true;
}
}
contain.push_back(flag2);//加入缺页的标志
if(flag2){
miss++;
}
memroyRecords.push_back(memory);
}
writeData("./output/LRU.txt"); //写出数据到文件
}
int LRU::SolveJobPage(int curLocation)
{
vector<int> recordIndex(memerySize,-1);//其实就是3个整型元素的向量,每一个的初始值定义为-1
int max = 1000;
int index = 0;
for(int i=0; i<memerySize; i++)
{
for(int j=0; j<curLocation; j++){
if(memory[i] == records[j]){
recordIndex[i] = j;
}
}
}
for(int i=0; i < memerySize; i++){
if(max > recordIndex[i]){
index = i;
max = recordIndex[i];
}
}
return index;
}
OPT
#include "OPT.h"
#include <fstream>
#include <ostream>
#include <cstdlib>
#include <cstring>
void OPT::execute()//子类实现自己的执行函数
//这个函数和前面FIFO的逻辑基本一致,区别在于下面的处理工作页面的换入换出
{
readData("./input/data.txt");
//读入数据
bool flag2=false;//设置一个缺页标志位初始化位缺页
int curPage;//当前页面
for(int i=0; i<records.size(); i++)
{
curPage = records[i];
flag2 =false;
if(!isContain(curPage))//
{
if (curMemorySize < memerySize)
{
memory[curMemorySize++] = records[i];
flag2 = true;
} else {
int pageIndex =SolveJobPage(i);
memory[pageIndex] = curPage;
flag2 = true;
}
}
contain.push_back(flag2);//加入缺页的标志
if(flag2){
miss++;
}
memroyRecords.push_back(memory);
}
writeData("./output/OPT.txt"); //写出数据到文件
}
//子类自己的页面换入换出处理
int OPT::SolveJobPage(int curLocation){
vector<int> recordIndex(memerySize,1000);//其实就是3个整型元素的向量,每一个的初始值定义为1000
for(int i=0; i<memerySize; i++){
for(int j = records.size()-1; j>curLocation; j--){
if(records[j] == memory[i] ){
recordIndex[i] = j; // 记录页面下一次出现的位置,,
//其实就是先知倒着看页面出现经过多少次后又被访问了,用来判断哪一个未来最长时间不被使用把他换掉
}
}
}
int max = -1;
int index = 0;
for(int i=0; i<memerySize; i++){
if(max < recordIndex[i]){
index = i;
max = recordIndex[i];
}
}
return index;
}
main方法
#include <iostream>
#include "OPT.h"
#include "FIFO.h"
#include "LFU.h"
#include "LRU.h"
using namespace std;
int main()
{
FIFO fifo;
fifo.execute();
cout<<"FIFO"<<endl;
fifo.show();
LRU lru;
lru.execute();
cout<<"LRU"<<endl;
lru.show();
LFU lfu;
lfu.execute();
cout<<"LFU"<<endl;
lfu.show();
OPT opt;
opt.execute();
cout<<"OPT"<<endl;
opt.show();
return 0;
}
运行结果
输入和输出的文件示例