整理整理代碼,方便一下學弟。
每年的題目細節可能改,可以按註釋自行修改代碼。
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <queue>
#include <stack>
using namespace std;
const int INF = 0x7fffffff;
int op;
struct node {
int pid;//進程號
int come;//進程到達時間
int run;//進程運行時間
int pri;//進程優先級
int rt;//進程時間片
}
tmp;
int cnt;
struct node que[101010];
bool vis[101010];
int nowp;
struct ANS {
int id;//運行序號
int pid;//進程號
int st;//進程開始運行時間
int en;//進程結束運行時間
int pri;//進程優先級
}ans;
node qu[101010];//就緒隊列
int he;//就緒隊列頭部
int ta;//就緒隊列尾部
void print(struct ANS e);//打印處理機所處理進程的信息,信息存儲在struct ANS結構中
bool fcfscmp(node a, node b);
//先來先服務算法進程排序規則,先按照到達時間升序,再按照進程號升序排列
bool spfcmp(node a, node b);
//短作業優先算法進程排序規則,先按照到達時間升序,再按照運行時間升序,再按進程號升序排列
bool rrcmp(node a, node b);
//時間片輪轉算法進程排序規則,先按照到達時間升序,再按照進程號升序排列
bool pricmp(node a, node b);
//動態優先級算法進程排序規則,先按照進程優先數升序,再按到達時間升序,再按進程號升序排列
void FCFS();//先來先服務調度算法
void SPF_N();//不可剝奪的短作業優先調度算法
void SPF_P();//可剝奪的短作業優先調度算法
void RR();//時間片輪轉調度算法
void PRI();//動態優先級調度算法
int main() {
cnt = 0;
scanf("%d", &op);//
int r = 0;
while (~scanf("%d/%d/%d/%d/%d", &tmp.pid, &tmp.come, &tmp.run, &tmp.pri, &tmp.rt)) {
que[++cnt] = tmp;
r++;
}
if (cnt == 0)return 0;
switch (op) {
case 1:FCFS();break;//先來先服務調度算法
case 2:SPF_N();break;//不可剝奪的短作業優先調度算法
case 3:SPF_P();break;//可剝奪的短作業優先調度算法
case 4:RR();break;//時間片輪轉調度算法
case 5:PRI();break;//動態優先級調度算法
}
system("pause");
return 0;
}
void PRI() {
int runtime = 0, nowtime = 0;//當前運行時間和進程運行總時間愛你
memset(vis, 0, sizeof(vis));
he = 1;ta = 0;
int t = 0;
ans.id = 0;
for (int i = 1;i <= cnt;i++)//計算進程運行總時間
runtime += que[i].run;
for (;;) {
for (int i = 1;i <= cnt;i++) {
if (vis[i] == 1)continue;
if (que[i].come <= t) {//將到達的進程加入就緒隊列
qu[++ta] = que[i];
vis[i] = 1;
}
}
if (ta < he) {//就緒隊列爲空時,時鐘加一,重新查找到達的進程
t++;
continue;
}
sort(qu + he, qu + ta + 1, pricmp);//將就緒隊列中的進程排序
qu[he].pri += 3;//運行一個時間片的進程優先數加三
ans.pri = qu[he].pri;
ans.id++;//運行進程信息
ans.pid = qu[he].pid;
ans.st = t;
t += min(qu[he].rt, qu[he].run);//運行時間爲需要運行時間和時間片的較小值
ans.en = t;
print(ans);
nowtime += ans.en - ans.st;
if (nowtime == runtime)return;//當前運行時間等於需要運行總時間時算法結束
node np = qu[he++];
for (int i = 1;i <= cnt;i++) {
if (vis[i] == 1)continue;
if (que[i].come<t) {//****將此刻之前的到達的進程都加入隊列,爲了後面的優先級改變
qu[++ta] = que[i];
vis[i] = 1;
}
}
for (int i = he;i <= ta;i++) {//將隊列中的進程優先級數加一
node tmp = qu[i];
tmp.pri -= 1;//每個隊列中的進程優先級數減一
if (tmp.pri < 0)//優先級數最小爲0
tmp.pri = 0;
qu[i] = tmp;
}
np.run -= (ans.en - ans.st);
if (np.run != 0)//當前程序沒有運行完,需要重新加入就緒隊列
qu[++ta] = np;
}
}
void RR() {
memset(vis, 0, sizeof(vis));
queue<node>q;//就緒隊列
int t = 0;
int runtime = 0, nowrun = 0;//當前運行時間和進程運行總時間
sort(que + 1, que + cnt + 1, rrcmp);//排序
for (int i = 1;i <= cnt;i++) { runtime += que[i].run; }//計算進程運行總時間
q.push(que[1]);vis[que[1].pid] = 1;//就緒隊列中加入第一個進程
int p = que[1].pid;
int ip;
node np = q.front();q.pop();
ans.id = 1;//第一個答案的信息
ip = 1;
t = np.come;
ans.st = np.come;
ans.pid = np.pid;
ans.pri = np.pri;
int flag1 = 0;
t += min(np.run, np.rt);//運行時間爲時間片和需要運行時間的較小值
//更改進程運行時間,並增加時鐘
for (;;) {
for (int i = 1;i <= cnt;i++) {
if (vis[que[i].pid] == 1 || que[i].pid == p)continue;
if (que[i].come <= t) {//將到達的進程加入就緒隊列,並標誌
q.push(que[i]);
vis[que[i].pid] = 1;
}
}
if (flag1 == 1) {//當前沒有程序運行
if (q.empty()) {//現在就緒隊列爲空
t++;//繼續時鐘加一
continue;
}
else {//就緒隊列不爲空
np = q.front();//取出首個進程運行
q.pop();p = np.pid;
ans.id++;//進程的信息
ans.pid = p;
ans.st = t;
ans.pri = np.pri;
t += min(np.run, np.rt); //更改進程運行時間,並增加時鐘
continue;
}
}
else if (np.run <= np.rt) {//當前有進程運行時,如果需要運行時間小於等於時間片
vis[p] = 1;
ans.en = t;
nowrun += ans.en - ans.st;
print(ans);//打印答案
if (nowrun == runtime)return;//如果當前運行時間等於進程運行總時間,算法結束
if (q.empty()) {//就緒隊列爲空
flag1 = 1;//標誌沒有進程運行
t++;
continue;
}
flag1 = 0;//標誌有進程運行
np = q.front();
q.pop();p = np.pid;
ans.id++;//進程具體信息
ans.pid = p;
ans.st = t;
ans.pri = np.pri;
t += min(np.run, np.rt);//更改進程運行時間,並增加時鐘
continue;
}
else {//當需要運行時間大於時間片,進程不會在這次運行完,還需要重新加入就緒隊列
np.run -= np.rt;
q.push(np);//重新加入就緒隊列
ans.en = t;
nowrun += ans.en - ans.st;
print(ans);
if (nowrun == runtime)return; //如果當前運行時間等於進程運行總時間,算法結束
flag1 = 0;//就緒隊列不爲空
np = q.front();//取出首個進程運行
q.pop();p = np.pid;
ans.id++;//進程運行信息
ans.pid = p;
ans.st = t;
ans.pri = np.pri;
t += min(np.run, np.rt); //更改進程運行時間,並增加時鐘
}
}
}
void SPF_P() {
memset(vis, false, sizeof(vis));
int t = 0;//時鐘t
int d;
int rt;
int p, q;
int nowrun = 0;//當前程序運行時間
int runtime = 0;//程序運行總時間
for (int i = 1;i <= cnt;i++)runtime += que[i].run;
sort(que + 1, que + 1 + cnt, spfcmp);//進程排序
int id = 1;
ans.id = 1;//第一個運行的進程
ans.st = que[1].come;
ans.pid = que[1].pid;
ans.pri = que[1].pri;
ans.en = ans.st;
p = 1;q = 2;
t = que[1].come + 1;
int flag1 = 0;
for (;;t++) {//時鐘每次加一
if (flag1 == 0) {//如果處理機正在處理進程,進程的運行時間加一,應該運行時間減一
ans.en++;que[p].run--;
}
while (q <= cnt && que[q].come <= t) { q++; }//將到達的進程加入就緒隊列
if (que[p].run == 0) {//當前正在運行的程序已經運行完
int mmin = INF;
for (int i = 1;i < q;i++) {//在就緒隊列中查找可以運行的進程
if (que[i].run == 0)continue;
if (que[i].run < mmin || (que[i].run == mmin&&que[i].come < que[p].come)) {
//選擇運行時間短,運行時間相同時到達時間早的進程
mmin = que[i].run;
p = i;
}
}
nowrun += ans.en - ans.st;
print(ans);
if (nowrun == runtime)return;//如果當前運行時間等於進程運行總時間,處理結束
if (mmin == INF) {//沒有找到可以運行的進程,也就是就緒隊列爲空
flag1 = 1;//標誌沒有進程正在進行,處理機空閒
continue;
}
flag1 = 0;//標誌處理機在處理進程
ans.id++;//更新答案數據
ans.st = t;
ans.pid = que[p].pid;
ans.pri = que[p].pri;
ans.en = ans.st;
}
else {
int mmin = INF;
int np;
for (int i = 1;i < q;i++) {//在就緒隊列中查找可以運行的進程
if (que[i].run == 0)continue;
if (que[i].run < mmin || (que[i].run == mmin&&que[i].come < que[np].come)) {
//選擇運行時間短,運行時間相同時到達時間早的進程
mmin = que[i].run;
np = i;
}
}
flag1 = 0; //標誌處理機在處理進程
if (mmin == INF)continue;
if (que[np].run < que[p].run || (que[np].run == que[p].run&&que[np].come < que[p].come)) {
//選擇運行時間短,運行時間相同時到達時間早的進程
nowrun += ans.en - ans.st;
print(ans);
if (nowrun == runtime)return; // 如果當前運行時間等於進程運行總時間,處理結束
p = np;
ans.id++;//更新答案數據
ans.st = t;
ans.en = t;
ans.pid = que[p].pid;
ans.pri = que[p].pri;
}
}
}
}
void SPF_N() {
int t = 0;//時鐘t
int p = 1;
for (int i = 1;i <= cnt;i++) {//每個進程只運行一次,一共運行cnt個進程
int flag1 = 0;
while (flag1 == 0) {//當就緒隊列中沒有進程時,時鐘t++,循環等待
for (int j = 1;j <= cnt;j++) {
if (que[j].run == 0)continue;//已經運行完成的進程
if (que[j].come > t)continue;//沒有到達的進程
if (que[j].come <= t&&flag1 == 0) {
p = j;
flag1 = 1;
}
else if (que[j].come <= t&&flag1 == 1) {
if ((que[j].run<que[p].run) || (que[j].run == que[p].run&&que[j].pid<que[p].pid)) {
//運行時間短的進程優先,運行時間相同時,進程號小的優先
p = j;
}
}
}
if (flag1 == 0)t++;//就緒隊列爲空,時鐘t++,循環等待
}
ans.id = i;//對結果信息賦值
ans.pid = que[p].pid;
ans.pri = que[p].pri;
ans.st = t;
ans.en = ans.st + que[p].run;
t = ans.en;
que[p].run = 0;
print(ans);//打印結果進程
}
return;
}
void FCFS() {
//將進程按照到達時間升序,進程號升序排列,然後按照排列依次運行各程序
int t = 0;
sort(que + 1, que + 1 + cnt, fcfscmp);//進程排序
for (int i = 1;i <= cnt;i++) {//依次運行各程序
ans.id = i;ans.pid = que[i].pid;
ans.st = max(t, que[i].come);
ans.en = ans.st + que[i].run;
ans.pri = que[i].pri;
t = ans.en;
print(ans);//打印程序的具體運行信息
}
return;
}
void print(struct ANS e) {
printf("%d/%d/%d/%d/%d\n", e.id, e.pid, e.st, e.en, e.pri);
}
bool fcfscmp(node a, node b) {
if (a.come != b.come)return a.come < b.come;
return a.pid < b.pid;
}
bool spfcmp(node a, node b) {
if (a.come != b.come)return a.come < b.come;
else if (a.run != b.run)return a.run < b.run;
else return a.pid < b.pid;
}
bool rrcmp(node a, node b) {
if (a.come != b.come)return a.come < b.come;
return a.pid < b.pid;
}
bool pricmp(node a, node b) {
if (a.pri != b.pri)return a.pri < b.pri;
if (a.come != b.come)return a.come < b.come;
return a.pid < b.pid;
}