#include<stdio.h>

#include<stdlib.h>

#include<time.h>

#include<string.h>

#include<math.h>


int Init(int *BlockList,int m,int *PageList,int n);                                                       //初始时刻内存块页面的装入

void PrintBlock(int *BlockList);                                                                          //输出当前内存块的页面

void OptimatAlgorithm(int *BlockList,int m,int *PageList,int n,int fl);                                   //最佳置换算法

void FIFOAlgorithm(int *BlockList,int m,int *PageList,int n,int fl);                                      //先进先出置换算法

void LRUAlgorithm(int *BlockList,int m,int *PageList,int n,int fl,int *FR);                               //最近最久未使用置换算法

void ClockAlgorithm(int *BlockList,int m,int *PageList,int n,int fl,int *Flag);                           //简单Clock置换算法

void ClockImproveAlgorithm(int *BlockList,int m,int *PageList,int n,int fl,int *Flag1,int * Flag2);       //改进Clock置换算法

void RandomAlgorithm(int *BlockList,int m,int *PageList,int n,int fl);                                    //随机置换算法


void PrintBlock(int *BlockList,int m)                         //输出当前内存块页面

{

int i = 0;

for(i = 0;i < m;i++)

{

if(i < m-1)

printf("%d ",BlockList[i]);

else

printf("%d",BlockList[i]);

}

printf("\n");

}



int Init(int *BlockList,int m,int *PageList,int n)

{

int i = 0,j = 0,count = 0,flag = 0,r = 0,ran,excount = 0;

for (i = 0;i < n;i++)                //初始时

{

if(i == 0)

{

BlockList[count] = PageList[i];

count ++;

}

else

{

for(j = 0;j < m;j++)

{

if(BlockList[j] == PageList[i])         //判断页面是否已在内存中

{

flag = 1;

j = m;

}

}

if(flag == 0)

{

BlockList[count] = PageList[i];

count ++;

}

flag = 0;

}

if(count == m )                       //初始内存已满

{

r = i;

i = n;

}

}

printf("当前内存块中的页面:");

PrintBlock(BlockList,m);                  //输出初始内存页面

return r+1;

}


void OptimatAlgorithm(int *BlockList,int m,int *PageList,int n,int fl)

{

int i = 0,j = 0,k = 0,r = 0;

int flag1 = 0,flag2 = 0,flag = 0;

int count1 = 0,excount = 0;

if(fl == 0)

r = Init(BlockList,m,PageList,n);

else

r = 0;

for(k = r;k<n;k++)

{

flag = 0;

for(j = 0;j < m;j++)                               //判断内存中是否已有该页面

{

if(PageList[k] == BlockList[j])

{

printf("页面%d,当前内存块中的页面:",PageList[k]);

PrintBlock(BlockList,m);

printf("没有发生置换\n");

flag = 1;

j = m;

}

}

if(flag == 0)                                    //如果没有则置换

{

for(j = 0;j<m;j++)

{

for(i = k;i<n;i++)                       //寻找被置换的页面

{

if(PageList[i] == BlockList[j])

{

if(i > flag1)

{

flag1 = i;                  //flag1记录当前被置换的页面

flag2 = j;                  //flag2记录被置换页面在内存块中的位置

}

i = n;

}

else

{

count1++;                       //count1用于判断内存中的页面是否在以后出现

}

}

if(count1 == n - k)

{

flag2 = j;                          //flag2记录被置换页面在内存块中的位置

j = m;

}

count1 = 0;

}

printf("页面%d,当前内存块中的页面:",PageList[k]);

PrintBlock(BlockList,m);

printf("应该被置换的页面:%d\n",BlockList[flag2]);

BlockList[flag2] = PageList[k];

printf("置换后内存块中的页面:");

PrintBlock(BlockList,m);

flag1 = 0;

flag2 = 0;

excount++;                      //记录置换次数

}

}

printf("最佳置换算法本次置换次数:%d,本次缺页率为:%c%.2f\n",excount,'%',(double)excount/(double)n*100);

}


void RandomAlgorithm(int *BlockList,int m,int *PageList,int n,int fl)

{

int i = 0,j = 0,count = 0,flag = 0,r = 0,ran,excount = 0;

if(fl == 0)

r = Init(BlockList,m,PageList,n);

else

r = 0;

srand((unsigned)time(NULL));

for(i = r;i<n;i++)

{

ran = rand()%m;                           //应该被淘汰出内存的页面

flag = 0;

for(j = 0;j < m;j++)

{

if(PageList[i] == BlockList[j])

{

printf("页面%d,当前内存块中的页面:",PageList[i]);

PrintBlock(BlockList,m);

printf("没有发生置换\n");

flag = 1;

j = m;

}

}

if(flag == 0)

{

printf("页面%d,当前内存块中的页面:",PageList[i]);

PrintBlock(BlockList,m);

printf("应该被置换的页面:%d\n",BlockList[ran]);

BlockList[ran] = PageList[i];

printf("置换后内存块中的页面:");

PrintBlock(BlockList,m);

excount++;

}

}

printf("随机置换算法本次置换次数:%d,本次缺页率为:%c%.2f\n",excount,'%',(double)excount/(double)n*100);

}


void FIFOAlgorithm(int *BlockList,int m,int *PageList,int n,int fl)

{

int i = 0,j = 0,count = 0,flag = 0,r = 0,excount = 0,k = 0,co = 0;;

if(fl == 0)

r = Init(BlockList,m,PageList,n);

else

r = 0;

for(k = r;k<n;k++)

{

flag = 0;

for(j = 0;j < m;j++)                     //判断内存中是否已有该页面

{

if(PageList[k] == BlockList[j])

{

printf("页面%d,当前内存块中的页面:",PageList[k]);

PrintBlock(BlockList,m);

printf("没有发生置换\n");

flag = 1;

j = m;

}

}

if(flag == 0)                                 //如果没有则置换

{

printf("页面%d,当前内存块中的页面:",PageList[k]);

PrintBlock(BlockList,m);

printf("应该被置换的页面:%d\n",BlockList[co]);

BlockList[co] = PageList[k];

printf("置换后内存块中的页面:");

PrintBlock(BlockList,m);

co = (co + 1)%m;

excount++;

}

}

printf("先进先出页面置换算法本次置换次数:%d,本次缺页率为:%c%.2f\n",excount,'%',(double)excount/(double)n*100);

}


void LRUAlgorithm(int *BlockList,int m,int *PageList,int n,int fl,int *FR)   //FR为寄存器

{

int i = 0,j = 0,k = 0,count = 0,excount = 0;

for(i = 0; i < n; i++)

{

if(count < m && fl == 0)           //初始时直接装入内存

{

for(j = 0;j <= count;j++)

{

if(PageList[i] == FR[j])

{

for(k = j;k <= count - 1;k++)

{

FR[k] = FR[k+1];

}

FR[count - 1] = PageList[i];

j = m;

}

else if(j == count)

{

FR[count] = PageList[i];

BlockList[count] = PageList[i];

count++;

j = m;

}

}

if(count == m)

{

printf("当前栈中页面顺序FR: ");

PrintBlock(FR,m);

printf("当前内存块中的页面:");

PrintBlock(BlockList,m);

}

}

else

{

for(j = 0;j < m;j++)

{

if(PageList[i] == FR[j])

{

for(k = j;k <= m - 1;k++)

{

FR[k] = FR[k+1];

}

FR[m - 1] = PageList[i];

printf("当前栈中页面顺序FR: ");

    PrintBlock(FR,m);

j = m;

}

else if(j == m - 1)

{

for(k = 0;k < m;k++)

{

if(BlockList[k] == FR[0])

{

printf("页面%d,当前内存块中的页面:",PageList[i]);

PrintBlock(BlockList,m);

printf("应该被置换的页面:%d\n",BlockList[k]);

BlockList[k] = PageList[i];

printf("置换后内存块中的页面:");

PrintBlock(BlockList,m);

excount++;

k = m;

}

}

for(k = 0;k < m - 1;k++)

{

FR[k] = FR[k+1];

}

FR[m - 1] = PageList[i];

printf("当前栈中页面顺序FR: ");

    PrintBlock(FR,m);

j = m;

}

}

}

}

printf("最近最久置换算法本次置换次数:%d,本次缺页率为:%c%.2f\n",excount,'%',(double)excount/(double)n*100);

}


void ClockAlgorithm(int *BlockList,int m,int *PageList,int n,int fl,int *Flag)

{

int i = 0,j = 0,k = 0,r = 0,flag = 0,count = 0,excount = 0;

if(fl == 0)

{

r = Init(BlockList,m,PageList,n);

for(i = 0;i < m;i++)

Flag[i] = 0;

}

else

r = 0;

for(i = r;i < n ;i++)

{

flag = 0;

for(j = 0;j < m;j++)                     //判断内存中是否已有该页面

{

if(PageList[i] == BlockList[j])

{

Flag[j] = 1;                     //访问位置1

printf("当前页面与内存中页面相等Flag: ");

PrintBlock(Flag,m);

flag = 1;

j = m;

}

}

if(flag == 0)                       //没有,需要置换

{

for(j = 0;j < m;j++)

{

if(Flag[count] == 0)

{

printf("置换前访问位Flag: ");

PrintBlock(Flag,m);

printf("页面%d,当前内存块中的页面:",PageList[i]);

PrintBlock(BlockList,m);

printf("应该被置换的页面:%d\n",BlockList[count]);

BlockList[count] = PageList[i];

printf("置换后内存块中的页面:");

PrintBlock(BlockList,m);

Flag[count] = 1;                     //访问位置1

count =(count + 1)%m; 

printf("置换后访问位Flag: ");

PrintBlock(Flag,m);

excount++;

j = m;

}

else

{

printf("当前访问位Flag: ");

PrintBlock(Flag,m);

Flag[count] = 0;

printf("修改当前访问位后Flag: ");

PrintBlock(Flag,m);

count = (count + 1)%m;

if(j == m-1)

j = 0;

}

}

}

}

printf("Clock置换算法的本次置换次数为:%d,本次缺页率为:%c%.2f\n",excount,'%',(double)excount/(double)n*100);

}


void ClockImproveAlgorithm(int *BlockList,int m,int *PageList,int n,int fl,int *Flag1,int *Flag2)

{

int i = 0,j = 0,k = 0,r = 0,flag = 0,count = 0,flag1 = 0,flag2 = 0,excount = 0;

if(fl == 0)

{

r = Init(BlockList,m,PageList,n);

for(i = 0;i < m;i++)

{

Flag1[i] = 0;

Flag2[i] = 0;

}

}

else

r = 0;

for(i = r;i < n ;i++)

{

flag = 0;

for(j = 0;j < m;j++)                     //判断内存中是否已有该页面

{

if(PageList[i] == BlockList[j])

{

Flag1[j] = 1;                     //访问位置1

printf("当前页面与内存中页面相等Flag1: ");

PrintBlock(Flag1,m);

flag = 1;

j = m;

}

}

if(flag == 0)                       //没有,需要置换

{

while(flag1 == 0 && flag2 == 0)

{

for(j = 0;j < m;j++)

{

if(Flag1[count] == 0 && Flag2[count] == 0)

{

printf("置换前访问位Flag1: ");

PrintBlock(Flag1,m);

BlockList[count] = PageList[i];

printf("置换前修改位Flag2: ");

PrintBlock(Flag2,m);

Flag2[count] = 1;                    //修改位置1

count =(count + 1)%m; 

flag1 = 1;

printf("第一步置换后内存页面:");

PrintBlock(BlockList,m);

printf("置换后访问位Flag1: ");

PrintBlock(Flag1,m);

printf("置换后修改位Flag2: ");

PrintBlock(Flag2,m);

excount++;

j = m;

}

count = (count+1)%m;

}

if(flag1 == 0)

{

for(j = 0;j < m;j++)

{

if(Flag1[count] == 0 && Flag2[count] == 1)

{

BlockList[count] = PageList[i];

Flag2[count] = 1;                    //修改位置1

count =(count + 1)%m; 

flag1 = 1;

flag2 = 1;

printf("第二步置换后内存页面:");

PrintBlock(BlockList,m);

printf("置换后访问位Flag1: ");

PrintBlock(Flag1,m);

printf("置换后修改位Flag2: ");

PrintBlock(Flag2,m);

excount++;

j = m;

}

Flag1[count] = 0;                    //访问位置0

printf("第二步扫描后访问位Flag1: ");

PrintBlock(Flag1,m);

printf("第二步扫描后修改位Flag2: ");

PrintBlock(Flag2,m);

count =(count + 1)%m; 

}

}

}

count = (count + m -1)%m;

flag1 = 0;

flag2 = 0;

}

}

printf("改进Clock置换算法的本次置换次数为:%d,本次缺页率为:%c%.2f\n",excount,'%',(double)excount/(double)n*100);

}