操作系统- 虚拟内存页面置换算法-详细设计附源码

2,544 阅读18分钟

一、需求分析

1、程序设计的任务和目的

通过这次实验,加深对虚拟内存页面置换概念的理解,进一步掌握先进先出FIFO、最佳置换OPI和最近最久未使用LRU页面置换算法的实现方法。

2、输入的形式和输入值的范围

最小物理块数m,页面个数n,页面访问序列P1, … ,Pn,算法选择1-FIFO,2-OPI,3-LRU。

3、输出的形式

每种算法的缺页次数和缺页率。

4、程序所能达到的功能

设计程序模拟先进先出FIFO、最佳置换OPI和最近最久未使用LRU页面置换算法的工作过程。假设内存中分配给每个进程的最小物理块数为m,在进程运行过程中要访问的页面个数为n,页面访问序列为P1, … ,Pn,分别利用不同的页面置换算法调度进程的页面访问序列,给出页面访问序列的置换过程,计算每种算法缺页次数和缺页率。

5、测试数据,包括正确的输入及其输出结果和含有错误的输入及其输出结果

正确用例

输入

请输入最小物理块数MinBlockNum:4
请输入页面个数PageNum:12
请输入页面1编号PageOrder[1]:4
请输入页面2编号PageOrder[2]:3
请输入页面3编号PageOrder[3]:2
请输入页面4编号PageOrder[4]:1
请输入页面5编号PageOrder[5]:4
请输入页面6编号PageOrder[6]:3
请输入页面7编号PageOrder[7]:5
请输入页面8编号PageOrder[8]:4
请输入页面9编号PageOrder[9]:3
请输入页面10编号PageOrder[10]:2
请输入页面11编号PageOrder[11]:1
请输入页面12编号PageOrder[12]:5

请选择想要先使用的算法( 1-先进先出(FIFO)页面置换算法,2-最佳(OPI)页面置换算法,3-最近最久未使用(LRU)页面置换算法 ):1

输出

请选择想要先使用的算法( 1-先进先出(FIFO)页面置换算法,2-最佳(OPI)页面置换算法,3-最近最久未使用(LRU)页面置换算法 ):1

您选择的是1-先进先出(FIFO)页面置换算法
页面7换掉第1物理块中的页面
页面8换掉第2物理块中的页面
页面9换掉第3物理块中的页面
页面10换掉第4物理块中的页面
页面11换掉第1物理块中的页面
页面12换掉第2物理块中的页面

页面置换算法模拟过程如下:
              Page 1    Page 2    Page 3    Page 4    Page 5    Page 6    Page 7    Page 8    Page 9    Page10    Page11    Page12
BlockNum 1         4         4         4         4         4         4         5         5         5         5         1         1
BlockNum 2                   3         3         3         3         3         3         4         4         4         4         5
BlockNum 3                             2         2         2         2         2         2         3         3         3         3
BlockNum 4                                       1         1         1         1         1         1         2         2         2
页面置换算法缺页次数为:10
页面置换算法缺页率为:83%

错误用例(输入中带有0页面,该页面号设置为状态量)

输入

请输入最小物理块数MinBlockNum:4
请输入页面个数PageNum:12
请输入页面1编号PageOrder[1]:4
请输入页面2编号PageOrder[2]:3
请输入页面3编号PageOrder[3]:2
请输入页面4编号PageOrder[4]:1
请输入页面5编号PageOrder[5]:4
请输入页面6编号PageOrder[6]:0
请输入页面7编号PageOrder[7]:5
请输入页面8编号PageOrder[8]:4
请输入页面9编号PageOrder[9]:0
请输入页面10编号PageOrder[10]:
2
请输入页面11编号PageOrder[11]:1
请输入页面12编号PageOrder[12]:0

请选择想要先使用的算法( 1-先进先出(FIFO)页面置换算法,2-最佳(OPI)页面置换算法,3-最近最久未使用(LRU)页面置换算法 ):2

输出

您选择的是2-最佳(OPI)页面置换算法
页面6于最远距离100换掉第2物理块中的页面
页面9于最远距离100换掉第1物理块中的页面
页面12于最远距离0换掉第0物理块中的页面

页面置换算法模拟过程如下:
              Page 1    Page 2    Page 3    Page 4    Page 5    Page 6    Page 7    Page 8    Page 9    Page10    Page11    Page12
BlockNum 1         4         4         4         4         4         4         4         4                   2         2         2
BlockNum 2                   3         3         3         3                   5         5         5         5         5         5
BlockNum 3                             2         2         2         2         2         2         2         2         2         2
BlockNum 4                                       1         1         1         1         1         1         1         1         1
页面置换算法缺页次数为:9
页面置换算法缺页率为:75%

二、概要设计

1、抽象数据类型的定义

int PageOrder[MaxNumber];//页面序列
int Simulate[MaxNumber][MaxNumber];//模拟过程
int PageNum;//页面数
int MinBlockNum;//最小物理块数
int LackNum;//缺页数
double LackPageRate;//缺页率
bool found;
int isAlgorithm;//算法选择

2、主程序的流程

int main() {
    virtualMemoryPageReplacementAlgorithm virtualMemoryPageReplacementAlgorithm{};

    virtualMemoryPageReplacementAlgorithm.Input();

    return 0;
}

3、各程序模块之间的层次(调用)关系

int main() {
    virtualMemoryPageReplacementAlgorithm virtualMemoryPageReplacementAlgorithm{};

    virtualMemoryPageReplacementAlgorithm.Input();

    return 0;
}

//输入函数调用InputAlgorithm函数选择输入函数
void Input() {
    ···
    InputAlgorithm();
}

//调用IsAlgorithm函数进行算法存储确认
void InputAlgorithm() {
    ···
    IsAlgorithm();
}

//算法确认后按照确认结果调用不同算法函数,若确认失败,要求重新输入
void IsAlgorithm() {
    ···
    switch (isAlgorithm) {
        case 1:
            AlgorithmFIFO();
        case 2:
            AlgorithmOPI();
        case 3:
            AlgorithmLRU();
        default:
            InputAlgorithm();
    }
}

//算法函数仅以FIFO为例,在完成算法处理后调用Print函数输出本算法运算结果,并调用NextAlgorithm函数询问下一算法使用
void AlgorithmFIFO() {
    ···

    Print();

    NextAlgorithm();
}

//询问后续,若有则重新调用算法确认函数循环流程,若触发终止条件结束进程
void NextAlgorithm() {
    ···
    IsAlgorithm();
}

三、详细设计

实现程序模块的具体算法

1、先进先出(FIFO)页面置换算法

//调用先进先出(FIFO)页面置换算法进行调度计算
void AlgorithmFIFO() {
    //初始化缺页次数
    LackNum = 0;
    //定义队列指针,指向下一个换出的页面
    int pointer = 0;

    for (int i = 1; i <= PageNum; i++) {
        //初始化found
        found = false;

        //如果是第一个页面,直接添加页面进Simulate[1][i],缺页数+1
        if (i == 1) {
            ···
            continue;
        }

        for (int j = 1; j <= MinBlockNum; j++) {
            //判断是否在物理块中,若存在,则此页面未缺页
            if (Simulate[j][i - 1] == PageOrder[i]) {
			    ···
                break;
            }

            //若缺页且有空物理块,则不置换,直接填入
            if (Simulate[j][i - 1] == 0) {
			    ···
                break;
            }
        }

        //若正常缺页,进行置换且输出置换步骤
        if (!found) {
            ···
        }
    }

    LackPageRate = (double) LackNum / (double) PageNum;

    Print();

    NextAlgorithm();
}

2、最佳(OPI)页面置换算法

//调用最佳(OPI)页面置换算法进行调度计算
void AlgorithmOPI() {
    //初始化缺页次数
    LackNum = 0;

    for (int i = 1; i <= PageNum; i++) {
        //初始化found
        found = false;
        //初始化队列指针,指向下一个换出的页面
        int pointer = 0;
        //初始化最远距离
        int distance = 0;

        //如果是第一个页面,直接添加页面,缺页数+1
        if (i == 1) {
            ···
            continue;
        }

        for (int j = 1; j <= MinBlockNum; j++) {
            //判断是否在物理块中,若存在,则此页面未缺页
			    ···
                break;
            }

            //若缺页且有空物理块,则不置换,直接填入
            if (Simulate[j][i - 1] == 0) {
			    ···
                break;
            }
        }

        if (!found) {
            for (int j = 1; j <= MinBlockNum; j++) {
                Simulate[j][i] = Simulate[j][i - 1];
                //寻找最优置换位
                for (int k = i + 1; k <= PageNum; k++) {
                    if (Simulate[j][i] == PageOrder[k]) {
                        if (k - i > distance) {
                            distance = k - i;
                            pointer = j;
                        }
                        break;
                    }
                    //判断页列表中无此需求,直接将此页面作为替换页面
                    if (k == PageNum && distance < MaxNumber) {
                        distance = MaxNumber;
                        pointer = j;
                    }
                }
            }
            
            ···
                
        }
    }

    LackPageRate = (double) LackNum / (double) PageNum;

    Print();

    NextAlgorithm();
}

3、最近最久未使用(LRU)页面置换算法

//调用最近最久未使用(LRU)页面置换算法进行调度计算
void AlgorithmLRU() {
    //初始化缺页次数
    LackNum = 0;

    for (int i = 1; i <= PageNum; i++) {
        //初始化found
        found = false;
        //初始化队列指针,指向下一个换出的页面
        int pointer = 0;
        //初始化最远距离
        int distance = 0;

        //如果是第一个页面,直接添加页面,缺页数+1
        if (i == 1) {
            ···
            continue;
        }

        for (int j = 1; j <= MinBlockNum; j++) {
            //判断是否在物理块中,若存在,则此页面未缺页
			    ···
                break;
            }

            //若缺页且有空物理块,则不置换,直接填入
            if (Simulate[j][i - 1] == 0) {
			    ···
                break;
            }
        }

        if (!found) {
            for (int j = 1; j <= MinBlockNum; j++) {
               Simulate[j][i] = Simulate[j][i - 1];
                //寻找最优置换位
                for (int k = i - 1; k > 0; k--) {
                    if (Simulate[j][i] == PageOrder[k]) {
                        if (i - k > distance) {
                            distance = i - k;
                            pointer = j;
                        }
                        break;
                    }
                    //判断页列表中无此需求,直接将此页面作为替换页面
                    if (k == 1 && distance < MaxNumber) {
                        distance = MaxNumber;
                        pointer = j;
                    }
                }
            }
            
            ···
                
        }
    }

    LackPageRate = (double) LackNum / (double) PageNum;

    Print();

    NextAlgorithm();
}

四、调试分析

调试过程中遇到的问题以及解决方法,设计与实现的回顾讨论和分析

问题 描述 解决方法
OPI、LRU算法同优先级处理问题 OPI、LRU算法中多个页面本页面序列中都不再使用时,因判定原因,会造成无限循环 使用if (k == 1 && distance < MaxNumber)条件语句解决本问题

算法的性能分析(包括基本操作和其它算法的时间复杂度和空间复杂度的分析)及其改进设想

性能分析

算法 时间复杂度 空间复杂度
先进先出(FIFO)页面置换算法 T(n) = O(n2) S(n) = O(n2)
最佳(OPI)页面置换算法 T(n) = O(n2) S(n) = O(n2)
最近最久未使用(LRU)页面置换算法 T(n) = O(n2) S(n) = O(n2)
Print数据输出 T(n) = O(n) S(n) = O(n2)
NextAlgorithm算法 T(n) = O(1) S(n) = O(1)

改进设想

设置页面0为状态符导致无法使用页面号为0的情况,可以考虑设计为数据结构

五、用户使用说明

使用说明

  • 控制台会提示要求用户进行输入,按提示输入内容即可
  • 不可输入页面0(该页面号设置为状态量)
  • 选择算法输入完成后将会输出虚拟内存页面置换过程及模拟列表
  • 可根据需要选择是否使用其他算法进行虚拟内存页面置换或退出

六、测试结果

测试结果,包括输入和输出

请输入最小物理块数MinBlockNum:4
请输入页面个数PageNum:12
请输入页面1编号PageOrder[1]:4
请输入页面2编号PageOrder[2]:3
请输入页面3编号PageOrder[3]:2
请输入页面4编号PageOrder[4]:1
请输入页面5编号PageOrder[5]:4
请输入页面6编号PageOrder[6]:3
请输入页面7编号PageOrder[7]:5
请输入页面8编号PageOrder[8]:4
请输入页面9编号PageOrder[9]:3
请输入页面10编号PageOrder[10]:2
请输入页面11编号PageOrder[11]:1
请输入页面12编号PageOrder[12]:5

请选择想要先使用的算法( 1-先进先出(FIFO)页面置换算法,2-最佳(OPI)页面置换算法,3-最近最久未使用(LRU)页面置换算法 ):1

您选择的是1-先进先出(FIFO)页面置换算法
页面7换掉第1物理块中的页面
页面8换掉第2物理块中的页面
页面9换掉第3物理块中的页面
页面10换掉第4物理块中的页面
页面11换掉第1物理块中的页面
页面12换掉第2物理块中的页面

页面置换算法模拟过程如下:
              Page 1    Page 2    Page 3    Page 4    Page 5    Page 6    Page 7    Page 8    Page 9    Page10    Page11    Page12
BlockNum 1         4         4         4         4         4         4         5         5         5         5         1         1
BlockNum 2                   3         3         3         3         3         3         4         4         4         4         5
BlockNum 3                             2         2         2         2         2         2         3         3         3         3
BlockNum 4                                       1         1         1         1         1         1         2         2         2
页面置换算法缺页次数为:10
页面置换算法缺页率为:83%

请问是否还要进行其余算法,若是,请输入(1-3值);若否,请输入任意字符( 1-先进先出(FIFO)页面置换算法,2-最佳(OPI)页面置换算法,3-最近最久未使用(LRU)页面置换算法 ):2

您选择的是2-最佳(OPI)页面置换算法
页面7于最远距离4换掉第4物理块中的页面
页面11于最远距离100换掉第1物理块中的页面

页面置换算法模拟过程如下:
              Page 1    Page 2    Page 3    Page 4    Page 5    Page 6    Page 7    Page 8    Page 9    Page10    Page11    Page12
BlockNum 1         4         4         4         4         4         4         4         4         4         4         1         1
BlockNum 2                   3         3         3         3         3         3         3         3         3         3         3
BlockNum 3                             2         2         2         2         2         2         2         2         2         2
BlockNum 4                                       1         1         1         5         5         5         5         5         5
页面置换算法缺页次数为:6
页面置换算法缺页率为:50%

请问是否还要进行其余算法,若是,请输入(1-3值);若否,请输入任意字符( 1-先进先出(FIFO)页面置换算法,2-最佳(OPI)页面置换算法,3-最近最久未使用(LRU)页面置换算法 ):3

您选择的是3-最近最久未使用(LRU)页面置换算法
页面7于最远距离4换掉第3物理块中的页面
页面10于最远距离6换掉第4物理块中的页面
页面11于最远距离4换掉第3物理块中的页面
页面12于最远距离4换掉第1物理块中的页面

页面置换算法模拟过程如下:
              Page 1    Page 2    Page 3    Page 4    Page 5    Page 6    Page 7    Page 8    Page 9    Page10    Page11    Page12
BlockNum 1         4         4         4         4         4         4         4         4         4         4         4         5
BlockNum 2                   3         3         3         3         3         3         3         3         3         3         3
BlockNum 3                             2         2         2         2         5         5         5         5         1         1
BlockNum 4                                       1         1         1         1         1         1         2         2         2
页面置换算法缺页次数为:8
页面置换算法缺页率为:67%

请问是否还要进行其余算法,若是,请输入(1-3值);若否,请输入任意字符( 1-先进先出(FIFO)页面置换算法,2-最佳(OPI)页面置换算法,3-最近最久未使用(LRU)页面置换算法 ):0

Process finished with exit code 0

七、附录

带注释的源程序

#include <iostream>
#include <iomanip>

using namespace std;
#define MaxNumber 100

class virtualMemoryPageReplacementAlgorithm {
public:

    int PageOrder[MaxNumber];//页面序列
    int Simulate[MaxNumber][MaxNumber];//模拟过程
//    int PageCount[MaxNumber];//当前内存距离下一次出现的距离
    int PageNum;//页面数
    int MinBlockNum;//最小物理块数
    int LackNum;//缺页数
    double LackPageRate;//缺页率
    bool found;
    int isAlgorithm;//算法选择

    //输入空闲分区数、空闲的分区大小、进程数、进程需要的分区大小
    void Input() {
        cout << "请输入最小物理块数MinBlockNum:";
        cin >> MinBlockNum;
        cout << "请输入页面个数PageNum:";
        cin >> PageNum;

        for (int i = 1; i <= PageNum; i++) {
            cout << "请输入页面" << i << "编号" << "PageOrder[" << i << "]:";
            cin >> PageOrder[i];
        }

        InputAlgorithm();
    }

    //获取算法选择输入
    void InputAlgorithm() {
        cout << endl
             << "请选择想要先使用的算法( 1-先进先出(FIFO)页面置换算法,2-最佳(OPI)页面置换算法,3-最近最久未使用(LRU)页面置换算法 ):";
        cin >> isAlgorithm;
        IsAlgorithm();
    }

    //算法存储确认
    void IsAlgorithm() {
        switch (isAlgorithm) {
            case 1:
                cout << endl << "您选择的是1-先进先出(FIFO)页面置换算法" << endl;
                AlgorithmFIFO();
                break;
            case 2:
                cout << endl << "您选择的是2-最佳(OPI)页面置换算法" << endl;
                AlgorithmOPI();
                break;
            case 3:
                cout << endl << "您选择的是3-最近最久未使用(LRU)页面置换算法" << endl;
                AlgorithmLRU();
                break;
            default:
                cout << "算法值:" << isAlgorithm
                     << "有误,请重新输入正确的算法类型( 1-先进先出(FIFO)页面置换算法,2-最佳(OPI)页面置换算法,3-最近最久未使用(LRU)页面置换算法 )"
                     << endl;
                InputAlgorithm();
        }
    }

    //询问是否还要进行其余算法
    void NextAlgorithm() {
        cout << endl
             << "请问是否还要进行其余算法,若是,请输入(1-3值);若否,请输入任意字符( 1-先进先出(FIFO)页面置换算法,2-最佳(OPI)页面置换算法,3-最近最久未使用(LRU)页面置换算法 ):";
        cin >> isAlgorithm;
        if (isAlgorithm != 1 && isAlgorithm != 2 && isAlgorithm != 3) {
            return;
        }
        IsAlgorithm();
    }

    //输出页面置换算法模拟过程及缺页次数与缺页率
    void Print() {

        cout << endl << "页面置换算法模拟过程如下:" << endl;

        //模拟过程
        cout << left << setw(10) << "";
        for (int i = 1; i <= PageNum; i++) {
            cout << right << setw(8) << "Page" << setw(2) << i;
        }

        for (int i = 1; i <= MinBlockNum; i++) {
            cout << endl << left << setw(8) << "BlockNum" << right << setw(2) << i;
            for (int j = 1; j <= PageNum; j++) {
                if (Simulate[i][j] != 0) {
                    cout << right << setw(10) << Simulate[i][j];
                } else {
                    cout << setw(10) << "";
                }
            }
        }

        cout << endl << "页面置换算法缺页次数为:" << LackNum << endl;

        cout << "页面置换算法缺页率为:" << setprecision(2) << LackPageRate * 100 << "%" << endl;

    }

    //调用先进先出(FIFO)页面置换算法进行调度计算
    void AlgorithmFIFO() {
        //初始化缺页次数
        LackNum = 0;
        //定义队列指针,指向下一个换出的页面
        int pointer = 0;

        for (int i = 1; i <= PageNum; i++) {
            //初始化found
            found = false;

            //如果是第一个页面,直接添加页面,缺页数+1
            if (i == 1) {
                Simulate[1][i] = PageOrder[i];
                LackNum++;
                pointer = 1;
                continue;
            }

            for (int j = 1; j <= MinBlockNum; j++) {
                //判断是否在物理块中,若存在,则此页面未缺页
                if (Simulate[j][i - 1] == PageOrder[i]) {
                    for (int k = 1; k <= MinBlockNum; k++) {
                        Simulate[k][i] = Simulate[k][i - 1];
                    }
                    found = true;
                    break;
                }

                //若缺页且有空物理块,则不置换,直接填入
                if (Simulate[j][i - 1] == 0) {
                    for (int k = 1; k <= MinBlockNum; k++) {
                        Simulate[k][i] = Simulate[k][i - 1];
                    }
                    Simulate[j][i] = PageOrder[i];
                    LackNum++;
                    found = true;
                    break;
                }
            }

            if (!found) {
                for (int j = 1; j <= MinBlockNum; j++) {
                    Simulate[j][i] = Simulate[j][i - 1];
                }
                cout << "页面" << i << "换掉第" << pointer << "物理块中的页面" << endl;
                Simulate[pointer][i] = PageOrder[i];
                LackNum++;
                if (pointer == MinBlockNum) {
                    pointer = 1;
                } else {
                    pointer++;
                }
            }
        }

        LackPageRate = (double) LackNum / (double) PageNum;

        Print();

        NextAlgorithm();
    }

    //调用最佳(OPI)页面置换算法进行调度计算
    void AlgorithmOPI() {
        //初始化缺页次数
        LackNum = 0;

        for (int i = 1; i <= PageNum; i++) {
            //初始化found
            found = false;
            //初始化队列指针,指向下一个换出的页面
            int pointer = 0;
            //初始化最远距离
            int distance = 0;

            //如果是第一个页面,直接添加页面,缺页数+1
            if (i == 1) {
                Simulate[1][i] = PageOrder[i];
                LackNum++;
                continue;
            }

            for (int j = 1; j <= MinBlockNum; j++) {
                //判断是否在物理块中,若存在,则此页面未缺页
                if (Simulate[j][i - 1] == PageOrder[i]) {
                    for (int k = 1; k <= MinBlockNum; k++) {
                        Simulate[k][i] = Simulate[k][i - 1];
                    }
                    found = true;
                    break;
                }

                //若缺页且有空物理块,则不置换,直接填入
                if (Simulate[j][i - 1] == 0) {
                    for (int k = 1; k <= MinBlockNum; k++) {
                        Simulate[k][i] = Simulate[k][i - 1];
                    }
                    Simulate[j][i] = PageOrder[i];
                    LackNum++;
                    found = true;
                    break;
                }
            }

            if (!found) {
                for (int j = 1; j <= MinBlockNum; j++) {
                    Simulate[j][i] = Simulate[j][i - 1];
                    //寻找最优置换位
                    for (int k = i + 1; k <= PageNum; k++) {
                        if (Simulate[j][i] == PageOrder[k]) {
                            if (k - i > distance) {
                                distance = k - i;
                                pointer = j;
                            }
                            break;
                        }
                        //判断页列表中无此需求,直接将此页面作为替换页面
                        if (k == PageNum && distance < MaxNumber) {
                            distance = MaxNumber;
                            pointer = j;
                        }
                    }
                }

                cout << "页面" << i << "于最远距离" << distance << "换掉第" << pointer << "物理块中的页面" << endl;

                Simulate[pointer][i] = PageOrder[i];
                LackNum++;
            }
        }

        LackPageRate = (double) LackNum / (double) PageNum;

        Print();

        NextAlgorithm();
    }

    //调用最近最久未使用(LRU)页面置换算法进行调度计算
    void AlgorithmLRU() {
        //初始化缺页次数
        LackNum = 0;

        for (int i = 1; i <= PageNum; i++) {
            //初始化found
            found = false;
            //初始化队列指针,指向下一个换出的页面
            int pointer = 0;
            //初始化最远距离
            int distance = 0;

            //如果是第一个页面,直接添加页面,缺页数+1
            if (i == 1) {
                Simulate[1][i] = PageOrder[i];
                LackNum++;
                continue;
            }

            for (int j = 1; j <= MinBlockNum; j++) {
                //判断是否在物理块中,若存在,则此页面未缺页
                if (Simulate[j][i - 1] == PageOrder[i]) {
                    for (int k = 1; k <= MinBlockNum; k++) {
                        Simulate[k][i] = Simulate[k][i - 1];
                    }
                    found = true;
                    break;
                }

                //若缺页且有空物理块,则不置换,直接填入
                if (Simulate[j][i - 1] == 0) {
                    for (int k = 1; k <= MinBlockNum; k++) {
                        Simulate[k][i] = Simulate[k][i - 1];
                    }
                    Simulate[j][i] = PageOrder[i];
                    LackNum++;
                    found = true;
                    break;
                }
            }

            if (!found) {
                for (int j = 1; j <= MinBlockNum; j++) {
                    Simulate[j][i] = Simulate[j][i - 1];
                    //寻找最优置换位
                    for (int k = i - 1; k > 0; k--) {
                        if (Simulate[j][i] == PageOrder[k]) {
                            if (i - k > distance) {
                                distance = i - k;
                                pointer = j;
                            }
                            break;
                        }
                        //判断页列表中无此需求,直接将此页面作为替换页面
                        if (k == 1 && distance < MaxNumber) {
                            distance = MaxNumber;
                            pointer = j;
                        }
                    }
                }

                cout << "页面" << i << "于最远距离" << distance << "换掉第" << pointer << "物理块中的页面" << endl;

                Simulate[pointer][i] = PageOrder[i];
                LackNum++;
            }
        }

        LackPageRate = (double) LackNum / (double) PageNum;

        Print();

        NextAlgorithm();
    }
};

int main() {
    virtualMemoryPageReplacementAlgorithm virtualMemoryPageReplacementAlgorithm{};

    virtualMemoryPageReplacementAlgorithm.Input();

    return 0;
}