PTA题目
注:在PTA上面提交时务必把scanf_s改成scanf,(编译器用的是vs2019).
主函数
int main() { int n; //进程数量 scanf_s("%d", &n); struct pcb p[100]; input(p,n); sort(p,n); sjf(p, n); output(p,n); return 0; }
核心算法
void sjf(struct pcb* p, int n) { int finishedcount = 0; //记录已经完成的进程数 int unfinishedposition = 0; // 记录未完成的进程的位置 double nowtime = 0; //现在时间 for (int i = 0; i < n; i++) { p[i].state = 0; } while (finishedcount < n) { //当已完成的进程数小于5时,一直循环 double minrtime = 1000000; // 中间量比较最短运行时间 int next = 0; //下一个要运行的进程位置 if (nowtime < p[unfinishedposition].atime * 1.0){ nowtime = p[unfinishedposition].atime * 1.0; next = unfinishedposition; } //扫描出有最短rtime的进程下标 for (int i = unfinishedposition; (i < n && nowtime >= p[i].atime&&i!=0); i++) { if (p[i].state == 1) { continue; //已经完成的退出本次执行 } if (p[i].rtime < minrtime) { minrtime = p[i].rtime; next = i; //记录下一个要执行的进程 } } //运行阶段 { nowtime =nowtime+p[next].rtime; p[next].state = 1; //记录完成运行 p[next].ftime = nowtime; //完成时间=现在时间 p[next].ttime = nowtime - p[next].atime; //周转=现在时间-到达 p[next].wtime = 1.0 * p[next].ttime / p[next].rtime; //带权周转=周转/运行 for (int i = unfinishedposition; i < n; i++) { //指向下一个未运行的进程 if (p[i].state == 0) { unfinishedposition = i; break; } } finishedcount++; //运行完成的个数 } } }
源程序代码
#include<stdio.h> #include<stdlib.h> //进程结构体 struct pcb{ char name[10]; //进程名 int atime; //到达时间 int rtime; //运行时间 int ftime; //完成时间 int ttime; //周转时间 double wtime; //带权周转时间 int state; //进程状态 }; //输入模块 void input(struct pcb* p, int n) { for (int i = 0; i < n; i++) { scanf_s("%s", p[i].name, sizeof(p[i])); } for (int i = 0; i < n; i++) { scanf_s("%d", &p[i].atime); } for (int i = 0; i < n; i++) { scanf_s("%d", &p[i].rtime); } } //输出模块 void output(struct pcb* p, int n) { printf("作 业 名:"); for (int i = 0; i < n; i++) { if (i == n - 1) { printf("%s", p[n - 1].name); printf("\n"); } else { printf("%s ", p[i].name); } } printf("到达时间:"); for (int i = 0; i < n; i++) { if (i == n - 1) { printf("%d", p[n - 1].atime); printf("\n"); } else { printf("%d ", p[i].atime); } } printf("服务时间:"); for (int i = 0; i < n; i++) { if (i == n - 1) { //最后一行要加回车 这样做其实不方便 printf("%d", p[n - 1].rtime); printf("\n"); } else { printf("%d ", p[i].rtime); } } printf("完成时间:"); for (int i = 0; i < n; i++) { if (i == n - 1) { printf("%d", p[n - 1].ftime); printf("\n"); } else { printf("%d ", p[i].ftime); } } printf("周转时间:"); for (int i = 0; i < n; i++) { if (i == n - 1) { printf("%d", p[n - 1].ttime); printf("\n"); } else { printf("%d ", p[i].ttime); } } printf("带权周转时间:"); for (int i = 0; i < n; i++) { if (i == n - 1) { printf("%.2f", p[n - 1].wtime); printf("\n"); } else { printf("%.2f ", p[i].wtime); } } } //atime升序 void sort(struct pcb* p, int n) { for (int i = 0; i < n - 1; i++) { struct pcb temp; for (int j = 0; j < n - i - 1; j++) { if (p[j].atime > p[j + 1].atime) { temp = p[j]; p[j] = p[j + 1]; p[j + 1] = temp; } } } } //短作业优先算法 void sjf(struct pcb* p, int n) { int finishedcount = 0; //记录已经完成的进程数 int unfinishedposition = 0; // 记录未完成的进程的位置 double nowtime = 0; //现在时间 for (int i = 0; i < n; i++) { p[i].state = 0; } while (finishedcount < n) { //当已完成的进程数小于5时,一直循环 double minrtime = 1000000; // 中间量比较最短运行时间 int next = 0; //下一个要运行的进程位置 if (nowtime < p[unfinishedposition].atime * 1.0){ nowtime = p[unfinishedposition].atime * 1.0; next = unfinishedposition; } //扫描出有最短rtime的进程下标 for (int i = unfinishedposition; (i < n && nowtime >= p[i].atime&&i!=0); i++) { if (p[i].state == 1) { continue; //已经完成的退出本次执行 } if (p[i].rtime < minrtime) { minrtime = p[i].rtime; next = i; //记录下一个要执行的进程 } } //运行阶段 { nowtime =nowtime+p[next].rtime; p[next].state = 1; //记录完成运行 p[next].ftime = nowtime; //完成时间=现在时间 p[next].ttime = nowtime - p[next].atime; //周转=现在时间-到达 p[next].wtime = 1.0 * p[next].ttime / p[next].rtime; //带权周转=周转/运行 for (int i = unfinishedposition; i < n; i++) { //指向下一个未运行的进程 if (p[i].state == 0) { unfinishedposition = i; break; } } finishedcount++; //运行完成的个数 } } } int main() { int n; //进程数量 scanf_s("%d", &n); struct pcb p[100]; input(p,n); sort(p,n); sjf(p, n); output(p,n); return 0; }
测试截图