操作系统课设(页面置换算法C++版)

运行结果

(1)data.txt文本文件:

请添加图片描述

                             图1 输入文件

将页面引用串输入到名为data.txt的文本文件中,以空格隔开。

(2)各种置换算法的输出结果:
请添加图片描述

                       图2 OPT页面置换算法运行结果

请添加图片描述

                      图3 FIFO页面置换算法运行结果

请添加图片描述

                        图4 LRU页面置换算法运行结果

请添加图片描述

                      图5 Clock页面置换算法运行结果

请添加图片描述

                       图6 LRU页面置换算法运行结果

完整代码

#include <iostream>
#include <vector>
#include <string>
#include <fstream>

#define random(a,b) (rand()%(b-a)+a)

using namespace std;

// 总虚页数
int t;
// 实页数
int size;
// 序列
vector<int> v;

// 7 0 1 2 0 3 0 4 2 3 0 3 2 1 2 0 1 7 0 1
void print(vector<pair<int, vector<int>>> res, int lackPageNum, int totalNum){

    for (int i = 0; i < size; ++i) {

        // 遍历每一个序列的第i个数
        for (int j = 0; j < res.size(); ++j) {
            printf("|");
            pair<int, vector<int>> cur = res[j];

            int isLack = cur.first;
            vector<int> v = cur.second;
            if(!isLack || v.size() < (i + 1)){
                printf("   ");
            }else{
                printf("%3d", v[i]);
            }
            printf("  ");
        }
        puts("|");
    }

    printf("缺页数为:%d\n", lackPageNum);
    printf("命中数:%d\n", (totalNum - lackPageNum));
    printf("缺页率为:%.3f%%\n", (lackPageNum * 100.0 / totalNum));
    printf("命中率为:%.3f%%\n", ((totalNum - lackPageNum) * 100.0 / totalNum));
}

void FIFO(){

    // 结果<是否缺页,页面>
    vector<pair<int, vector<int>>> res;

    // 上一页
    vector<int> pre;

    // 判断是否缺页的
    bool flag;

    int lackPageNum = 0;

    for(int num: v){

        flag = true; // 是否缺页

        for (int i = 0; i < pre.size(); ++i) {
            if(num == pre[i]){
                flag = false;
            }
        }

        if(!flag){
            res.push_back(make_pair(0, vector<int>(pre.begin(), pre.end())));
            continue;
        }

        lackPageNum++;

        if(pre.size() < size){

            pre.push_back(num);

        }else{

            // 缺页则换出队头
            pre.erase(pre.begin());
            pre.push_back(num);
        }

        res.push_back(make_pair(1, vector<int>(pre.begin(), pre.end())));
    }

    printf("FIFO(先进先出)算法:\n");
    print(res, lackPageNum, t);
    puts("");
    puts("");
}

void LRU(){

    // <是否缺页,页面>
    vector<pair<int, vector<int>>> res;

    // 上一页
    vector<int> pre;

    // 判断是否缺页的
    bool flag;
    // 缺页数
    int lackPageNum = 0;

    // 当前页在队中那个位置
    int idx = 0;

    for(int num: v){

        flag = true; // 是否缺页

        for (int i = 0; i < pre.size(); ++i) {
            if(num == pre[i]){
                flag = false;
                idx = i;
            }
        }

        if(!flag){
            // 换到队头
            pre.erase(pre.begin() + idx);
            pre.insert(pre.begin(), num);
            res.push_back(make_pair(0, vector<int>(pre.begin(), pre.end())));
            continue;
        }

        lackPageNum++;

        if(pre.size() < size){
            pre.insert(pre.begin(), num);
        }else{
            // 缺页则换出队尾
            pre.erase(pre.end()-1);
            pre.insert(pre.begin(), num);
        }

        res.push_back(make_pair(1, vector<int>(pre.begin(), pre.end())));
    }

    printf("LRU(最近最久未使用)算法:\n");
    print(res, lackPageNum, t);
    puts("");
    puts("");
}

void OPT(){

    // <是否缺页,页面>
    vector<pair<int, vector<int>>> res;

    // 上一页
    vector<int> pre;

    // 判断是否缺页的
    bool flag;
    // 缺页数
    int lackPageNum = 0;

    for(int k = 0; k < v.size(); k++){

        int num = v[k];
        flag = true; // 是否缺页

        for (int i = 0; i < pre.size(); ++i) {
            if(num == pre[i]){
                flag = false;
            }
        }

        if(!flag){
            res.push_back(make_pair(0, vector<int>(pre.begin(), pre.end())));
            continue;
        }

        lackPageNum++;

        if(pre.size() < size){
            pre.push_back(num);
        }else{
            // 最后面的数在v中的位置
            int last = -1;
            // 最后面的数在pre中的位置
            int idx;
            // 当前pre[i] 是否存在与v中
            bool isExit;
            // 缺页则换出pre中在v序列最后面的或者不在后面的序列的
            for (int i = 0; i < pre.size(); ++i) {
                isExit = false;
                for (int j = k + 1; j < v.size(); ++j) {
                    if(pre[i] == v[j]){
                        isExit = true;
                        if(j > last){
                            idx = i;
                            last = j;
                        }
                        break;
                    }
                }
                // 当前pre[i] 根本不在v中,则直接退出循环
                if(!isExit){
                    idx = i;
                    break;
                }
            }

            pre.erase(pre.begin() + idx);
            pre.insert(pre.begin()+ idx, num);
        }

        res.push_back(make_pair(1, vector<int>(pre.begin(), pre.end())));
    }

    printf("OPT(最佳)置换算法:\n");
    print(res, lackPageNum, t);
    puts("");
    puts("");
}

void setToOne(int &num, int idx){
    num = num + (1 << idx);
}

// 统一右移
void rightMove(vector<pair<int, int>> & visNum){

//    puts("");
    for(pair<int, int> &p: visNum){
//        printf("%d ", p.second);
        p.second = p.second >> 1;
    }

//    puts("");
}
// 判断是否在visNum中
bool isExit(vector<pair<int, int>> & visNum, int num){
    for(pair<int, int> &p: visNum){
        if(p.first == num){
            return true;
        }
    }
    return false;
}
// 找到某个数在队列中的索引
int findIdx(vector<pair<int, int>> & visNum, int num){
    for (int i = 0; i < visNum.size(); ++i) {
        pair<int, int> p = visNum[i];
        if(p.first == num){
            return i;
        }
    }
    return -1;
}

// 找到 freq 最小的在 pre 中的位置
int findMinIdx(vector<pair<int, int>> visNum, vector<int> pre){

    int id = -1;
    int min = (1 << 31) - 1;

    for (int i = 0; i < pre.size(); ++i) {
        for (int j = 0; j < visNum.size(); ++j) {
            pair<int, int> p = visNum[j];
            if(pre[i] == p.first && p.second < min){
                id = i;
                min = p.second;
            }
        }
    }
    return id;
}

void LFU(){

    vector<pair<int, vector<int>>> res;
    vector<int> pre;

    // 记录访问频率<数, 频率>
    vector<pair<int, int>> visNum;
    int lackPageNum = 0;

    for (int num: v) {

        bool flag = true;
        rightMove(visNum);

        for (int i = 0; i < pre.size(); ++i) {
            if(pre[i] == num){
                flag = false;
            }
        }

        if(!flag){
            int idx = findIdx(visNum, num);
            setToOne(visNum[idx].second, 30);
            res.push_back(make_pair(0, vector<int>(pre.begin(), pre.end())));
            continue;
        }

        lackPageNum++;

        bool isEx = isExit(visNum, num);

        if(pre.size() < size){
            pre.push_back(num);
            visNum.push_back({num, (1 << 30)});
        }else{

            if(!isEx){
                visNum.push_back({num, (1 << 30)});
            }else{
                int idx = findIdx(visNum, num);
                setToOne(visNum[idx].second, 30);
            }

            int idx = findMinIdx(visNum, pre);

            pre.erase(pre.begin() + idx);
            pre.push_back(num);
        }

        res.push_back(make_pair(1, vector<int>(pre.begin(), pre.end())));
    }

    printf("LFU(最少使用)置换算法:\n");
    print(res, lackPageNum, t);

    puts("");
    puts("");
}

// 1 3 4 2 5 6 3 4 7
void CLK(){

    vector<pair<int, vector<int>>> res;

    vector<int> pre;
    int vis[t + 5];

    int lackPageNum = 0;
    bool flag;

    // 指针
    int idx = 0;

    for (int num: v) {
        flag = true;
        for (int i = 0; i < pre.size(); ++i) {
            if(pre[i] == num){
                vis[i] = 1;
                flag = false;
            }
        }

        if(!flag){
            res.push_back(make_pair(0, vector<int>(pre.begin(), pre.end())));
            continue;
        }

        lackPageNum++;

        if(pre.size() < size){
            pre.push_back(num);
            vis[pre.size()-1] = 1;
        }else{

            while (true){

                if(!vis[idx]){
                    pre.erase(pre.begin() + idx);
                    pre.insert(pre.begin() + idx, num);
                    vis[idx] = 1;
                    idx = (idx + 1) % size;
                    break;
                }

                vis[idx] = 0;
                idx = (idx + 1) % size;
            }
        }

        res.push_back(make_pair(1, vector<int>(pre.begin(), pre.end())));
    }

    printf("NRU(最近未用)置换算法:\n");
    print(res, lackPageNum, t);

    puts("");
    puts("");
}


void init1(){

    printf("可用物理块大小:");
    scanf("%d", &size);
    printf("调入序列长度:");
    scanf("%d", &t);

    int num;

    printf("请输入调入页面序列:");

    printf("");
    for (int i = 0; i < t; ++i) {
        scanf("%d", &num);
        v.push_back(num);
    }
}

void init2(){

    ifstream df("../data.txt");

    if (!df.is_open()){

        cout << "Error opening file";
        exit (1);
    }
    df >> size;
    df >> t;
    int num;
    for (int i = 0; i < t; ++i) {
        df >> num;
        v.push_back(num);
    }

    df.close();
}

void init3(){

    int a = 1, b = 10;
    size = 3;
    t = 20;
    int num;

    for (int i = 0; i < t; ++i) {
        num = random(a, b);
        v.push_back(num);
    }
}

int main(){

//    int num = 1;
//    setToOne(num, 4);
//    cout << num;

//    init1();
    init2();
//    init3();

    printf("\n\n\n访问序列:");
    for (int i = 0; i < v.size(); ++i) {
        printf("%d  ", v[i]);
    }

    puts("");

    FIFO();
    LRU();
    OPT();
    LFU();
    CLK();


    // Test
//    vector<pair<int, int>> vp;
//    vp.push_back({3, 8});
//    rightMove(vp);
//    setToOne(vp[0].second, 30);
//    cout << vp[0].second;

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值