#include <stdio.h>
#include <stdlib.h>
/*全局变量*/
int mSIZE; //物理块数
int pSIZE; //页面号引用串个数
static int memery[10]={0}; //物理块中的页号
static int page[100]={0}; //页面号引用串
static int temp[100][10]={0}; //辅助数组
/*置换算法函数*/
void FIFO();
void LRU();
void OPT();
/*辅助函数*/
void print(unsigned int t);
/*主函数*/
void main()
{
int i,k,code;
printf("请输入物理块的个数(M<=10):");
scanf("%d",&mSIZE);
printf("请输入页面号引用串的个数(P<=100):");
scanf("%d",&pSIZE);
puts("请依次输入页面号引用串(用空格隔开):");
for(i=0;i<pSIZE;i++)
scanf("%1d",&page[i]);
system("cls");
do{
puts("\n 输入的页面号引用串为:");
for(k=0;k<=(pSIZE-1)/20;k++)
{
for(i=20*k;(i<pSIZE)&&(i<20*(k+1));i++)
{
if(((i+1)%20==0)||(((i+1)%20)&&(i==pSIZE-1)))
printf("%d\n",page[i]);
else
printf("%d ",page[i]);
}
}
printf("*************************************************\n");
printf("*\t请选择页面置换算法: *\n");
printf("*\t\t\t\t\t\t*\n");
printf("*\t1.最佳置换算法(OPT) *\n");
printf("*\t2.先进先出算法(FIFO) *\n");
printf("*\t3.最近最久未使用(LRU) *\n");
printf("*\t4.退出 *\n");
printf("*************************************************\n");
printf("请选择操作:[ ]\b\b");
scanf("%d",&code);
printf("\n");
switch(code)
{
case 1:
OPT();
break;
case 2:
FIFO();
break;
case 3:
LRU();
break;
case 4:
system("cls");
exit(0);
default:
printf("\n输入错误,请重新输入!!!\n\n\n");
}
}while (code!=4);
getchar();
}
void print(unsigned int t)
{
int i,j,k,l;
int flag;
for(k=0;k<=(pSIZE-1)/20;k++)
{
for(i=20*k;(i<pSIZE)&&(i<20*(k+1));i++)
{
if(((i+1)%20==0)||(((i+1)%20)&&(i==pSIZE-1)))
printf("%d\n",page[i]);
else
printf("%d ",page[i]);
}
for(j=0;j<mSIZE;j++)
{
for(i=20*k;(i<mSIZE+20*k)&&(i<pSIZE);i++)
{
if(i>=j)
printf(" |%d|",temp[i][j]);
else
printf(" | |");
}
for(i=mSIZE+20*k;(i<pSIZE)&&(i<20*(k+1));i++)
{
for(flag=0,l=0;l<mSIZE;l++)
if(temp[i][l]==temp[i-1][l])
flag++;
if(flag==mSIZE) //页面在物理块中
printf(" ");
else
printf(" |%d|",temp[i][j]);
}
printf("\n");
}
}
printf("\n------------------------------------------\n");
printf(" 缺页次数:%d\t\t",t+mSIZE);
printf("缺页率:%d/%d\n",t+mSIZE,pSIZE);
printf(" 置换次数:%d\t\t",t);
printf("访问命中率:%d%%\n",(pSIZE-(t+mSIZE))*100/pSIZE);
printf("------------------------------------------\n");
}
/*先进先出页面置换算法*/
void FIFO()
{
int memery[10]={0};
int time[10]={0}; //记录进入物理块的时间
int i,j,k,m;
int max=0; //记录换出页
int count=0; //记录置换次数
/*前mSIZE个数直接放入*/
for(i=0;i<mSIZE;i++)
{
memery[i]=page[i];
time[i]=i;
for(j=0;j<mSIZE;j++)
temp[i][j]=memery[j];
}
for(i=mSIZE;i<pSIZE;i++)
{
/*判断新页面号是否在物理块中*/
for(j=0,k=0;j<mSIZE;j++)
{
if(memery[j]!=page[i])
k++;
}
if(k==mSIZE) //如果不在物理块中
{
count++;
/*计算换出页*/
max=time[0]<time[1]?0:1;
for(m=2;m<mSIZE;m++)
if(time[m]<time[max])
max=m;
memery[max]=page[i];
time[max]=i; //记录该页进入物理块的时间
for(j=0;j<mSIZE;j++)
temp[i][j]=memery[j];
}
else
{
for(j=0;j<mSIZE;j++)
temp[i][j]=memery[j];
}
}
print(count);
}
/*最近最久未使用置换算法*/
void LRU()
{
int memery[10]={0};
int flag[10]={0}; //记录页面的访问时间
int i,j,k,m;
int max=0; //记录换出页
int count=0; //记录置换次数
/*前mSIZE个数直接放入*/
for(i=0;i<mSIZE;i++)
{
memery[i]=page[i];
flag[i]=i;
for(j=0;j<mSIZE;j++)
temp[i][j]=memery[j];
}
for(i=mSIZE;i<pSIZE;i++)
{
/*判断新页面号是否在物理块中*/
for(j=0,k=0;j<mSIZE;j++)
{
if(memery[j]!=page[i])
k++;
else
flag[j]=i; //刷新该页的访问时间
}
if(k==mSIZE) //如果不在物理块中
{
count++;
/*计算换出页*/
max=flag[0]<flag[1]?0:1;
for(m=2;m<mSIZE;m++)
if(flag[m]<flag[max])
max=m;
memery[max]=page[i];
flag[max]=i; //记录该页的访问时间
for(j=0;j<mSIZE;j++)
temp[i][j]=memery[j];
}
else
{
for(j=0;j<mSIZE;j++)
temp[i][j]=memery[j];
}
}
print(count);
}
/*最佳置换算法*/
void OPT()
{
int memery[10]={0};
int next[10]={0}; //记录下一次访问时间
int i,j,k,l,m;
int max; //记录换出页
int count=0; //记录置换次数
/*前mSIZE个数直接放入*/
for(i=0;i<mSIZE;i++)
{
memery[i]=page[i];
for(j=0;j<mSIZE;j++)
temp[i][j]=memery[j];
}
for(i=mSIZE;i<pSIZE;i++)
{
/*判断新页面号是否在物理块中*/
for(j=0,k=0;j<mSIZE;j++)
{
if(memery[j]!=page[i])
k++;
}
if(k==mSIZE) //如果不在物理块中
{
count++;
/*得到物理快中各页下一次访问时间*/
for(m=0;m<mSIZE;m++)
{
for(l=i+1;l<pSIZE;l++)
if(memery[m]==page[l])
break;
next[m]=l;
}
/*计算换出页*/
max=next[0]>=next[1]?0:1;
for(m=2;m<mSIZE;m++)
if(next[m]>next[max])
max=m;
/*下一次访问时间都为pSIZE,则置换物理块中第一个*/
memery[max]=page[i];
for(j=0;j<mSIZE;j++)
temp[i][j]=memery[j];
}
else {
for(j=0;j<mSIZE;j++)
temp[i][j]=memery[j];
}
}
print(count);
}