操作系统 页面置换算法 面向对象实现 C/C++ FIFO,LRU,LFU,OPT(需要源码的自取)

项目的结构

源码已放在网盘,需要代码自取

链接: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;
}

运行结果

在这里插入图片描述

输入和输出的文件示例

在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值