先到先服务(FCFS)算法C语言,Java语言实现

来源:互联网 发布:如何取消淘宝店铺差评 编辑:程序博客网 时间:2024/06/05 14:51

输入如下:

4
A   8.00   1.00
B   8.50   0.50
C   9.00   0.10
D   9.50   0.20

输出如下:



C代码:

#include <stdio.h>#include <stdlib.h>#define INF 1000000.0struct PCB {    char id[10];    // 进程ID    double reachTime;  // 进程到达的时间    double needTime;   // 进程完成需要的时间    double startTime;  // 进程开始的时刻    double finishTime; // 进程完成的时刻    double cTime;      // 进程周转时间    double wcTime;     // 进程带权周转时间    char state;       // 进程的状态( 设每个进程处于就绪R(ready),完成F(finish)两种状态之一 )};int cmp( const void *a, const void *b ) {    if( ((struct PCB*)a)->reachTime < ((struct PCB*)b)->reachTime ) return -1;    return 1;}int main() {    int num, i;    double lastTime;  // 为上一个进程的完成时间,用来确定当前进程的开始时间    struct PCB *arr;    printf( "请输入进程数:" );    scanf( "%d", &num );    arr = (struct PCB*)malloc(num*sizeof(struct PCB));    lastTime = INF;  // 最开始lastTime的为第一个作业的reachTime(到达时间)    printf( "请依次输入进程ID,进程到达时间,进程运行时间:\n" );    for( i = 0; i < num; i++ ) {        scanf( "%s%lf%lf", arr[i].id, &arr[i].reachTime, &arr[i].needTime );        arr[i].state = 'R';        if( lastTime>arr[i].reachTime ) lastTime = arr[i].reachTime;    }    qsort( arr, num, sizeof(struct PCB), cmp ); // 将进程按reachTime(到达时间)进行排序    // sum1为所有进程周转时间之和,sum2为所有进程带权周转时间之和    double sum1=0.0, sum2=0.0;    for( i = 0; i < num; i++ ) {        int p = i; // 找到下一个将要执行的进程        // 两种情况:将要执行的进程可能已经到达,或者还没到达        if( arr[p].reachTime<=lastTime ) arr[p].startTime = lastTime;        else arr[p].startTime = arr[p].reachTime;        // 确定进程的完成时间,周转时间,带权周转时间        arr[p].finishTime = arr[p].startTime + arr[p].needTime;        arr[p].cTime = arr[p].finishTime - arr[p].reachTime;        arr[p].wcTime = arr[p].cTime/arr[p].needTime;        arr[p].state = 'F';        sum1 += arr[p].cTime;        sum2 += arr[p].wcTime;        lastTime = arr[p].finishTime; // 更新lastTime    }    printf( "\n进程  到达时间  运行时间  开始时间  完成时间  周转时间  带权周转时间\n" );    for( i = 0; i < num; i++ ) {        printf( "%4s  %8.2lf  %8.2lf  ", arr[i].id, arr[i].reachTime, arr[i].needTime );        printf( "%8.2lf  %8.2lf  ", arr[i].startTime, arr[i].finishTime );        printf( "%8.2lf  %12.2lf\n", arr[i].cTime, arr[i].wcTime );    }    printf( "平均周转时间: %.3lf\n", sum1/num );    printf( "平均带权周转时间: %.3lf\n", sum2/num );    return 0;}


如果要实现短作业优先算法,可以将第42行的代码改成 int p = findNext( arr, num, lastTime );

再添下面的函数即可实现:

/* 两种情况:    1.在lastTime时刻,选择已经到达且拥有最短运行时间的进程    2.在lastTime时刻,没有进程到达,此时选择拥有最早到达时间的进程*/int findNext( struct PCB arr[], int length, double lastTime ) {    int i, p=-1;    double minNeedTime = INF;    for( i = 0; i < length; i++ ) {        if( arr[i].state=='R' ) { // 进程处就绪状态            /* 数组arr已经按reachTime排序,当出现       arr[i].reachTime>lastTime时,说明在lastTime时刻无进程到达,终止循环.*/            if( arr[i].reachTime > lastTime ) break;            if( arr[i].needTime<minNeedTime )                { p = i; minNeedTime = arr[i].needTime; }        }    }    // p为-1时,代表在lastTime时刻还没进程到达,此时选择下一个最早到达的进程i    if( p != -1 ) return p;    return i;}


Java代码:

import java.util.Scanner;import java.util.Arrays;public class Main {// 接口Comparable和类方法Arrays.sort()的配合使用可以使进程按reachTime(到达时间)排序    private static class PCB implements Comparable<PCB> {    String id;float reachTime;float needTime;float startTime;float finishTime;char state;public int compareTo( PCB b ) {if( reachTime==b.reachTime ) return 0;if( reachTime<b.reachTime ) return -1;return 1;}}    public static void main( String[] args ) {    Scanner sc = new Scanner( System.in );System.out.print( "请输入进程数:" );int num = sc.nextInt();PCB[] arr = new PCB[num];System.out.println( "请依次输入进程ID,进程到达时间,进程运行时间:" );for( int i = 0; i < num; i++ ) {    arr[i] = new PCB();arr[i].id = sc.next();arr[i].reachTime = sc.nextFloat();arr[i].needTime = sc.nextFloat();arr[i].state = 'R';}Arrays.sort(arr); // 使进程按reachTime(到达时间)排序float lastTime=arr[0].reachTime;for( int i=0; i<num; i++ ) {    // 找到下一个将要执行的进程    int p = i;if( arr[p].reachTime<lastTime ) arr[p].startTime = lastTime;else arr[p].startTime = arr[p].reachTime;arr[p].finishTime = arr[p].startTime + arr[p].needTime;arr[p].state = 'F';lastTime = arr[p].finishTime;  // 更新lastTime}float sum1=0.0f, sum2=0.0f;System.out.println( "\n进程  到达时间  运行时间  开始时间  完成时间  周转时间  带权周转时间" );for( PCB jcb : arr ) {System.out.format( "%4s  %8.2f  %8.2f  ", jcb.id, jcb.reachTime, jcb.needTime );    System.out.format( "%8.2f  %8.2f  ", jcb.startTime, jcb.finishTime );System.out.format( "%8.2f  ", jcb.finishTime-jcb.reachTime );System.out.format( "%12.2f\n", (jcb.finishTime-jcb.reachTime)/jcb.needTime );sum1 += jcb.finishTime-jcb.reachTime;sum2 += (jcb.finishTime-jcb.reachTime)/jcb.needTime;}System.out.format( "平均周转时间: %.3f\n", (sum1/num) );System.out.format( "平均带权周转时间: %.3f", (sum2/num) );}}


同样Java代码的第39行改成 int p = findNext( arr, lastTime );

并添加以下函数可实现短作业优先算法:

private static final float INF = 10000000.0f;/* 两种情况:   1.在lastTime时刻,选择已经到达且拥有最短运行时间的进程   2.在lastTime时刻,没有进程到达,此时选择拥有最早到达时间的进程*/private static int findNext( PCB[] arr, float lastTime ){    int i, p = -1;    float minNeedTime = INF;    for( i = 0; i < arr.length; i++ )    {        if( arr[i].state=='R' )        {            /* 数组arr已经按reachTime排序,当出现               arr[i].reachTime>lastTime时,说明在lastTime时刻无进程到达,终止循环.*/            if( arr[i].reachTime > lastTime ) break;            if( arr[i].needTime < minNeedTime )            {                p = i;                minNeedTime = arr[i].needTime;            }        }    }    if( p != -1 ) return p;    return i;}