=============================================================================================
20131115_第一次修改
ccb_warlock
=============================================================================================
前几周操作系统留下了一个课后作业,内容是写一个根据程序总资源、空闲资源、当前分配资源和请求资源来判断当前系统是否处于安全状态的小程序。其实根据内容来说并不算难,不需要特别复杂的结构和算法,但是在编写时还是遇到了一些问题。
版本编号:01
源码部分:
#include
<iostream>
using namespace
std;
int main()
{
int E[4];
int A[4];
int C[3][4];
int R[3][4];
int i=0,j=0;
cout<<"输入总资源向量:"<<endl;
for(i=0;i<4;i++)
cin>>E[i];
cout<<"输入空闲资源向量:"<<endl;
for(i=0;i<4;i++)
cin>>A[i];
cout<<"输入当前分配矩阵:"<<endl;
for(i=0;i<3;i++)
for(j=0;j<4;j++)
cin>>C[i][j];
cout<<"输入请求矩阵:"<<endl;
for(i=0;i<3;i++)
for(j=0;j<4;j++)
cin>>R[i][j];
int sentry=0;
int flag=0;
for(i=0;i<3;i++)
{
for(j=0;j<4;j++)
if(R[i][j]<=A[j])
flag++;
if(flag==4)
{
for(j=0;j<4;j++)
A[i]+=C[i][j];
sentry++;
}
}
if(sentry==3)
cout<<"该系统处于安全状态。"<<endl;
else
cout<<"该系统处于不安全状态。"<<endl;
return
0;
}
问题1:
当我写完第一个程序后,发现每次都会多做一次加法运算,虽然这段程序仅仅只是一个测试程序,但是为了解决这个问题我还是将源码进行了改进。
版本编号:02
源码部分:
#include
<iostream>
using
namespace std;
int
main()
{
int E[4];
int A[4];
int C[3][4];
int R[3][4];
int i=0,j=0;
cout<<"输入总资源向量:"<<endl;
for(i=0;i<4;i++)
cin>>E[i];
cout<<"输入空闲资源向量:"<<endl;
for(i=0;i<4;i++)
cin>>A[i];
cout<<"输入当前分配矩阵:"<<endl;
for(i=0;i<3;i++)
for(j=0;j<4;j++)
cin>>C[i][j];
cout<<"输入请求矩阵:"<<endl;
for(i=0;i<3;i++)
for(j=0;j<4;j++)
cin>>R[i][j];
int sentry=0;
int flag=0;
for(i=0;i<3;i++)
{
for(j=0;j<4;j++)
if(R[i][j]<=A[j])
flag++;
if(flag==4)//满足小于条件
{
flag=0;
sentry++;
if(sentry!=3)
{
for(j=0;j<4;j++)
{
A[j]+=C[i][j];
}
}
}
}
if(sentry==3)
cout<<"该系统处于安全状态。"<<endl;
else
cout<<"该系统处于不安全状态。"<<endl;
return
0;
}
根据上面的修改注释说明了改进的部分。
问题2:
上面程序有个可以改进的地方在于其操作的数组均发生了数据上的修改,其实为了保护数据的原始状态,我们完全可以通过映射的方式通过对映射数组的运算达到我们的需求。
同时我们也可以利用一个函数来封装我们的运算,对于结果而言我们只在乎其是否为安全状态,故使用bool型的函数算是一个合理的选择。
版本编号:03
源码部分:
#include
<iostream>
using namespace std;
bool fun();
int E[4];
int A[4];
int C[3][4];
int R[3][4];
int main()
{
int i=0,j=0;
cout<<"输入总资源向量:"<<endl;
for(i=0;i<4;i++)
cin>>E[i];
cout<<"输入空闲资源向量:"<<endl;
for(i=0;i<4;i++)
cin>>A[i];
cout<<"输入当前分配矩阵:"<<endl;
for(i=0;i<3;i++)
for(j=0;j<4;j++)
cin>>C[i][j];
cout<<"输入请求矩阵:"<<endl;
for(i=0;i<3;i++)
for(j=0;j<4;j++)
cin>>R[i][j];
if( fun()
)
cout<<"该系统处于安全状态。"<<endl;
else
cout<<"该系统处于不安全状态。"<<endl;
return 0;
}
bool fun()
{
int e[4];
int a[4];
int c[3][4];
int r[3][4];
int x=0,y=0;
int sentry=0;
int flag=0;
for(x=0;x<4;x++)
{
e[x]=E[x];
a[x]=A[x];
}
for(x=0;x<3;x++)
for(y=0;y<4;y++)
{
c[x][y]=C[x][y];
r[x][y]=R[x][y];
}
for(x=0;x<3;x++)
{
for(y=0;y<4;y++)//按元素顺序进行检测
if(r[x][y]<=a[y])
flag++;
if(flag==4)//满足小于条件
{
sentry++;
if(sentry!=3)
{
for(y=0;y<4;y++)
{
a[y]+=c[x][y];
}
}
}
}
if(sentry==3)
return true;
else
return false;
}
问题3:
由于赶着交作业,我并没有完全核查源码,测试的数据也没几组,知道期中考试前准备总结本次编写的思路时核查源码之下,才发现上述程序有着许多错误。
首先最明显的就是进行的运算根本连循环都没有,由于当时测试的数据样本少,并没有出现该问题,实际上检测的次数是要根据数据的运算后回溯再进行运算。
于是我想到添加一个while循环来保证能够回溯运算,至于条件,暂时以一个bool类型的值来判断,但是对于lock值的修改需要看本次遍历时是否有符合要求的行向量出现,此时我们就加一个bool类型的state来判断本次遍历的状态。但是仅仅添加上面的还不够,我们还需要一个能判断是否每一行的向量是否已经经过了运算,所以我们需要再为每个行向量各添加一个状态位,我们用一个bool型的数组sign[3]来标记。
版本编号:04
源码部分:
#include
<iostream>
using namespace std;
bool fun();
int E[4];
int A[4];
int C[3][4];
int R[3][4];
int main()
{
int i=0,j=0;
cout<<"输入总资源向量:"<<endl;
for(i=0;i<4;i++)
cin>>E[i];
cout<<"输入空闲资源向量:"<<endl;
for(i=0;i<4;i++)
cin>>A[i];
cout<<"输入当前分配矩阵:"<<endl;
for(i=0;i<3;i++)
for(j=0;j<4;j++)
cin>>C[i][j];
cout<<"输入请求矩阵:"<<endl;
for(i=0;i<3;i++)
for(j=0;j<4;j++)
cin>>R[i][j];
if( fun()
)
cout<<"该系统处于安全状态。"<<endl;
else
cout<<"该系统处于不安全状态。"<<endl;
return 0;
}
bool fun()
{
int e[4];
int a[4];
int c[3][4];
int r[3][4];
int x=0,y=0;
int sentry=0;
int flag=0;
bool sign[3];//行向量的标记数组
bool state=false;//满足要求的行的临时状态位
bool lock=true;//循环的锁定状态位
for(x=0;x<4;x++)
{
e[x]=E[x];
a[x]=A[x];
}
for(x=0;x<3;x++)
for(y=0;y<4;y++)
{
c[x][y]=C[x][y];
r[x][y]=R[x][y];
}
for(x=0;x<3;x++)
{
sign[x]=false;
}
while(lock)
{
for(x=0;x<3;x++)
{
if(state==false &&
sign[x]==false)
{
for(y=0;y<4;y++)//按元素顺序进行检测
if(r[x][y]<=a[y])
flag++;
if(flag==4)//满足小于条件
{
sentry++;
lock=true;//如果该行向量满足小于要求,则解除锁定
sign[x]=true;
state=true;
if(sentry!=3)
{
for(y=0;y<4;y++)
{
a[y]+=c[x][y];
}
}
break;
}
else//不满足小于条件
{
lock=false;
}
}
}
state=false;
if(sign[0]==true && sign[1]==true
&& sign[2]==true)
{
lock=false;
}
}
if(sentry==3)
return true;
else
return false;
}
问题4:
运行之后当检测样本数据多了之后还是存在错误,于是再次查看一遍源码后才发现原来一直忘做了一件十分重要的操作,在标志位flag使用前先做一次初始化。
版本编号:05
源码部分:
#include
<iostream>
using namespace std;
bool fun();
int E[4];
int A[4];
int C[3][4];
int R[3][4];
int main()
{
int i=0,j=0;
cout<<"输入总资源向量:"<<endl;
for(i=0;i<4;i++)
cin>>E[i];
cout<<"输入空闲资源向量:"<<endl;
for(i=0;i<4;i++)
cin>>A[i];
cout<<"输入当前分配矩阵:"<<endl;
for(i=0;i<3;i++)
for(j=0;j<4;j++)
cin>>C[i][j];
cout<<"输入请求矩阵:"<<endl;
for(i=0;i<3;i++)
for(j=0;j<4;j++)
cin>>R[i][j];
if( fun()
)
cout<<"该系统处于安全状态。"<<endl;
else
cout<<"该系统处于不安全状态。"<<endl;
return 0;
}
bool fun()
{
int e[4];
int a[4];
int c[3][4];
int r[3][4];
int x=0,y=0;
int sentry=0;
int flag=0;
bool sign[3];//行向量的标记数组
bool state=false;//满足要求的行的临时状态位
bool lock=true;//循环的锁定状态位
for(x=0;x<4;x++)
{
e[x]=E[x];
a[x]=A[x];
}
for(x=0;x<3;x++)
for(y=0;y<4;y++)
{
c[x][y]=C[x][y];
r[x][y]=R[x][y];
}
for(x=0;x<3;x++)
{
sign[x]=false;
}
while(lock)
{
for(x=0;x<3;x++)
{
if(state==false &&
sign[x]==false)
{
for(y=0;y<4;y++)//按元素顺序进行检测
if(r[x][y]<=a[y])
flag++;
if(flag==4)//满足小于条件
{
flag=0;
sentry++;
lock=true;//如果该行向量满足小于要求,则解除锁定
sign[x]=true;
state=true;
//
cout<<"s=
"<<sentry<<endl;//检测时用
if(sentry!=3)
{
for(y=0;y<4;y++)
{
a[y]+=c[x][y];
}
}
break;
}
else//不满足小于条件
{
flag=0;
lock=false;
}
}
}
state=false;
if(sign[0]==true && sign[1]==true
&& sign[2]==true)
{
lock=false;
}
}
//
cout<<"s_over=
"<<sentry<<endl;//检测时用
//
cout<<"a
"<<a[0]<<"
"<<a[1]<<"
"<<a[2]<<"
"<<a[3]<<endl;//检测时用
if(sentry==3)
return true;
else
return false;
}
程序重构到这里基本将问题解决了,这次的的编写程序让我总结了很多。首先是对一个题目需要全面的构思,当然也会出现许多考虑不周的地方,这需要我们多做检查与思考来修正。
其次是对于条件的总和判定,我们可以通过增加适当的标志位来反映某些属性的状态。再者就是对于一些变量的使用需根据进行某些操作(比如初始化)。最后,对于程序正确性的检验我们也需要构造一定量的测试数据来检验,毕竟从代码的角度考虑有时会不足,通过测试数据与结果反馈有时能发现编写时的错误并为修改提供方向。
即使有一天在技术上我已经是个能手,请记住自己应有的责任和保持一个真诚交流、始终渴望追求技术的心。
----------ccb_warlock