1.数据
输入数据由三部分组成:
2.结构体
四种算法的数据组成是一样的,所以使用相同的结构体(全局变量在最后完整代码中)
struct P
{
string name; //名称
int arrive,longg,start,endd,cyc;//到达时间,服务时间,开始时间,结束时间,周转时间
double qcyc;//平均周转时间
int id;//数据顺序
}p[10000];
因为在调度中顺序会改变,所以要保留输入时的数据顺序,这样才能按原本顺序输出
3.FCFS
这个算法只按照到达时间排序,且不会因为后面的进程而改变顺序,因此只需要全部排一次就可以
bool cmpFCFS(P p1,P p2)
{
return p1.arrive<p2.arrive;//按到达时间从小到大
}
void FCFS(string infilename,string outfilename)//(输入文件名与保存文件名)
{
readfile(infilename);//读入数据(可改为手动输入)
sort(p,p+n,cmpFCFS);//sort不解释,cmp是自定义排序方式,如上
now=0;//当前时间
for(int i=0;i<n;i++)
{
now=max(now,p[i].arrive);//如果当前无到达进程,则直接跳到下一个到来进程的到达时间
p[i].start=now;//p[i]开始执行
now+=p[i].longg;//p[i]时间
p[i].endd=now;//p[i]执行完毕
}
savefile(outfilename);//保存数据
}
4.HRRN
这个排序会受后来进程影响,所以每执行完一个就要重排,但因为一次执行一个进程,所以只需要找到优先级最高的,即p[0]是优先级最高,因此只需和p[0]比较,而不用全部sort排序,执行完的交换到数组最后,进程数n-1,则将已执行完进程排除序列
void sortHRRN()
{
for(int i=1;i<n;i++)
{
if(p[0].arrive>now&&p[i].arrive>now&&p[0].arrive>p[i].arrive)//都未达,先到达先开始
swap(p[0],p[i]);
else if(p[0].arrive<=now&&p[i].arrive<=now&&(double)1.0*(now-p[0].arrive+p[0].longg)/p[0].longg<(double)1.0*(now-p[i].arrive+p[i].longg)/p[i].longg)//都已达,根据HRRN规则计算,得到优先级较高的
swap(p[0],p[i]);
else if(p[0].arrive>now)//剩下两种情况都是一个已达,一个未达,已达的排在前,所以p[0]未达则交换,p[0]已达则不动
swap(p[0],p[i]);
}
}
void HRRN(string infilename,string outfilename)
{
readfile(infilename);
now=0;
while(n>0){
sortHRRN();//每次找
now=max(now,p[0].arrive);
p[0].start=now;
now+=p[0].longg;
p[0].endd=now; //同上
swap(p[0],p[n-1]);
n--;//排除已执行
}
savefile(outfilename);
}
5.SPF
基本同上,仅排序规则不同
void sortSPF()
{
for(int i=1;i<n;i++)
{
if(p[0].arrive>now&&p[i].arrive>now&&p[0].arrive>p[i].arrive)
swap(p[0],p[i]);
else if(p[0].arrive<=now&&p[i].arrive<=now&&p[0].longg>p[i].longg)//此处不同
swap(p[0],p[i]);
else if(p[0].arrive>now)
swap(p[0],p[i]);
}
}
void SPF(string infilename,string outfilename)
{
readfile(infilename);
now=0;
while(n>0){
sortSPF();
now=max(now,p[0].arrive);
p[0].start=now;
now+=p[0].longg;
p[0].endd=now;
swap(p[0],p[n-1]);
n--;
}
savefile(outfilename);
}
6.SRT
排序规则与SPF一样,但它能够抢占,所以最简单的方法就是每执行一个时间单位就重排一次,而且因为要改变longg值来记录,所以在开始要保留初始longg值,执行完回复原数据,还要注意开始时间的记录
void sortSRT()//与SPF完全一致
{
for(int i=1;i<n;i++)
{
if(p[0].arrive>now&&p[i].arrive>now&&p[0].arrive>p[i].arrive)
swap(p[0],p[i]);
else if(p[0].arrive<=now&&p[i].arrive<=now&&p[0].longg>p[i].longg)
swap(p[0],p[i]);
else if(p[0].arrive>now)
swap(p[0],p[i]);
}
}
void SRT(string infilename,string outfilename)
{
readfile(infilename);
now=0;
int l[10000];//记录longg的数组
for(int i=0;i<n2;i++)
{
l[i]=p[i].longg;//记录
}
while(n>0){
sortSRT();
now=max(now,p[0].arrive);
if(p[0].start==-1)//已开始的不用记录开始时间
p[0].start=now;
now++;//执行一时间单位
p[0].longg--;//执行一时间单位
if(!p[0].longg)//执行结束
{
p[0].endd=now;
swap(p[0],p[n-1]);
n--;
}
}
sort(p,p+n2,cmpfirst);//恢复原顺序
for(int i=0;i<n2;i++)
{
p[i].longg=l[i];//恢复longg
}
savefile(outfilename);
}
完整代码
#include<iostream>
#include<algorithm>
#include<cmath>
#include<ostream>
#include<sstream>
#include<fstream>
#include<iomanip>
#include<stdio.h>
using namespace std;
struct P
{
string name;
int arrive,longg,start,endd,cyc;
double qcyc;
int id;
}p[10000];
int n,n2,now,choice;
string s;
bool cmpfirst(P p1,P p2)
{
return p1.id<p2.id;
}
void split(string s)
{
stringstream sstream;
string s2;
int l1=0,l2=0;
while(s[l1]!=' ')
l1++;
l2=l1+1;
while(s[l2]!=' ')
l2++;
p[n].name=s.substr(0,l1);
s2=s.substr(l1+1,l2-l1-1);
sstream<<s2;
sstream>>p[n].arrive;
sstream.clear();
s2=s.substr(l2+1,s.length()-l2-1);
sstream<<s2;
sstream>>p[n].longg;
p[n].id=n;
p[n].start=-1;
//p[n].start=stoi(s.substr(l1+1,l2-l1-1));
//p[n].longg=stoi(s.substr(l2+1,s.length()-l2-1));
//cout<<p[n].name<<" "<<p[n].start<<" "<<p[n].longg<<endl;
}
void readfile(string infilename)
{
n=0;
ifstream infile(infilename);
if (!infile.is_open())
{
cout << "file can't open" << endl;
}
getline(infile,s);
while(getline(infile,s))
{
split(s);
n++;
}
n2=n;
infile.close();
}
void savefile(string outfilename)
{
sort(p,p+n2,cmpfirst);
cout<<"finish"<<endl;
ofstream outfile(outfilename, ios::app);
switch(choice)
{
case 1:outfile<<"FCFS:"<<endl;break;
case 2:outfile<<"SPF:"<<endl;break;
case 3:outfile<<"HRRN:"<<endl;break;
case 4:outfile<<"SRT:"<<endl;break;
default:;
}
outfile<<"name\tarrive\tlongg\tstart\tend\tcyc\tqcyc"<<endl;
for(int i=0;i<n2;i++)
{
p[i].cyc=p[i].endd-p[i].arrive;
p[i].qcyc=1.0*p[i].cyc/p[i].longg;
outfile<<left<<setw(7)<<p[i].name
<<left<<setw(7)<<p[i].arrive
<<left<<setw(7)<<p[i].longg
<<left<<setw(7)<<p[i].start
<<left<<setw(7)<<p[i].endd
<<left<<setw(7)<<p[i].cyc
<<left<<setw(7)<<p[i].qcyc<<endl;
}
outfile.close();
}
bool cmpFCFS(P p1,P p2)
{
return p1.arrive<p2.arrive;
}
void FCFS(string infilename,string outfilename)
{
readfile(infilename);
sort(p,p+n,cmpFCFS);
now=0;
for(int i=0;i<n;i++)
{
now=max(now,p[i].arrive);
p[i].start=now;
now+=p[i].longg;
p[i].endd=now;
}
savefile(outfilename);
}
void sortHRRN()
{
for(int i=1;i<n;i++)
{
if(p[0].arrive>now&&p[i].arrive>now&&p[0].arrive>p[i].arrive)
swap(p[0],p[i]);
else if(p[0].arrive<=now&&p[i].arrive<=now&&(double)1.0*(now-p[0].arrive+p[0].longg)/p[0].longg<(double)1.0*(now-p[i].arrive+p[i].longg)/p[i].longg)
swap(p[0],p[i]);
else if(p[0].arrive>now)
swap(p[0],p[i]);
}
}
void HRRN(string infilename,string outfilename)
{
readfile(infilename);
now=0;
while(n>0){
sortHRRN();
now=max(now,p[0].arrive);
p[0].start=now;
now+=p[0].longg;
p[0].endd=now;
swap(p[0],p[n-1]);
n--;
}
savefile(outfilename);
}
void sortSPF()
{
for(int i=1;i<n;i++)
{
if(p[0].arrive>now&&p[i].arrive>now&&p[0].arrive>p[i].arrive)
swap(p[0],p[i]);
else if(p[0].arrive<=now&&p[i].arrive<=now&&p[0].longg>p[i].longg)
swap(p[0],p[i]);
else if(p[0].arrive>now)
swap(p[0],p[i]);
}
}
void SPF(string infilename,string outfilename)
{
readfile(infilename);
now=0;
while(n>0){
sortSPF();
now=max(now,p[0].arrive);
p[0].start=now;
now+=p[0].longg;
p[0].endd=now;
swap(p[0],p[n-1]);
n--;
}
savefile(outfilename);
}
void sortSRT()
{
for(int i=1;i<n;i++)
{
if(p[0].arrive>now&&p[i].arrive>now&&p[0].arrive>p[i].arrive)
swap(p[0],p[i]);
else if(p[0].arrive<=now&&p[i].arrive<=now&&p[0].longg>p[i].longg)
swap(p[0],p[i]);
else if(p[0].arrive>now)
swap(p[0],p[i]);
}
}
void SRT(string infilename,string outfilename)
{
readfile(infilename);
now=0;
int l[10000];
for(int i=0;i<n2;i++)
{
l[i]=p[i].longg;
}
while(n>0){
sortSRT();
now=max(now,p[0].arrive);
if(p[0].start==-1)
p[0].start=now;
now++;
p[0].longg--;
if(!p[0].longg)
{
p[0].endd=now;
swap(p[0],p[n-1]);
n--;
}
}
sort(p,p+n2,cmpfirst);//恢复原顺序
for(int i=0;i<n2;i++)
{
p[i].longg=l[i];
}
savefile(outfilename);
}
int main()
{
string infilename,outfilename;
cout<<"input the filename:";
cin>>infilename;
cout<<"input the name of saved file:";
cin>>outfilename;
choice = 1;//初始化choice
while(choice != 0)
{
cout<<"input your choice:0.exit 1.FCFS 2.SPF 3.HRRN 4.SRT"<<endl;
cin>>choice;
switch(choice)
{
case 1:FCFS(infilename,outfilename);break;
case 2:SPF(infilename,outfilename);break;
case 3:HRRN(infilename,outfilename);break;
case 4:SRT(infilename,outfilename);break;
case 0:cout<<"退出程序\n";break;
default:cout<<"";
}
}
return 0;
}
哦对了ifstream infile(infilename);这种写法至少c++11才能运行(传入一个string),或者你可以全部改成c的形式:在string变量名后面加个.c_str(),就像这样->ifstream infile(infilename.c_str());
有疑问欢迎在评论区指出(っ•̀ω•́)っ✎⁾⁾ 我爱学习