您现在的位置是:首页 >技术交流 >湖北师范大学操作系统实验网站首页技术交流
湖北师范大学操作系统实验
个人写法,不喜勿喷。有更好方法欢迎私信交流!
题目1:进程调度1—静态非剥夺式优先级调度计算平均作业周转时间
问题描述:要求输入3个进程的信息,假设这些进程均是在0时刻同时到达,若进程调度采用非剥夺式静态优先级(优先数数值大的表示优先级比较高;如果遇到优先级一样,按照输入顺序执行。),计算并输出平均作业周转时间。
输入格式:程序要求输入3行,以回车符号作为分隔,每行有3个数据,以空格作为分隔。首先输入一个字符串(长度小于等于10),为进程名,第2个数据类型为整型,表示进程的优先数,第3个数据类型为整型,表示进程的运行时间。
输出格式:输出结果为一个浮点数,保留到小数点后一位,为系统的平均作业周转时间。
样例输入1:
P1 1 1
P2 2 2
P3 3 3
样例输出1:
4.7
样例输入2:
P1 10 10
P2 100 100
P3 100 100
样例输出2:
170.0
#include <stdio.h>
#include <stdlib.h>
typedef struct {
char name[50];
int priority;
int time;
} process;
int main() {
process p1, p2, p3;
process mc[3] = {p1, p2, p3};
int i, j;
double sum = 0, total = 0, avg = 0;
for (i = 0; i < 3; i++) {
scanf("%s %d %d", mc[i].name, &mc[i].priority, &mc[i].time);
}
for (i = 0; i < 2; i++) {
for (j = 0; j < 2 - i; j++) {
if (mc[j].priority < mc[j+1].priority) {
process temp = mc[j+1];
mc[j+1] = mc[j];
mc[j] = temp;
}
}
}
for (i = 0; i < 3; i++) {
sum = 0;
for (j = 0; j <= i; j++) {
sum += mc[j].time;
}
total += sum;
}
avg = total / 3;
printf("%.1f", avg);
return 0;
}
题目2:进程调度2--最高响应比优先计算每个作业的周转时间
问题描述:要求输入3个进程的信息,按照最高响应比优先的调度算法计算并输出每个进程的周转时间。(若两个进程的响应比相同,则优先选择先进入的进程。若两个进程的响应比相同,而且进入时刻也相同,则按照输入的顺序执行,如:P4和P6的响应比相同且进入时刻也相同,如P4先输入则选择P4先执行)
输入格式:程序要求输入3行,以回车符号作为分隔,每行有3个数据,以空格作为分隔。首先输入一个字符串(长度小于等于10),为进程名,第2个数据类型为整型,表示进程的进入时刻,第3个数据类型为整型,表示进程的运行时间。
输出格式:输出三个整数之间,整数之间用空格作为分隔,为每个进程的周转时间。
样例输入1:
P1 1 1
P2 2 2
P3 3 3
样例输出1:
1 2 4
样例输入2:
P1 1 4
P2 2 8
P3 3 1
样例输出2:
4 12 3
import java.util.Arrays;
import java.util.Scanner;
public class Second {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String[] line = new String[3];
for(int i=0;i<3;i++){
line[i] = scanner.nextLine();
}
String[][] process = {line[0].split(" "),line[1].split(" "),line[2].split(" ")};
Arrays.sort(process,(a,b) -> Integer.parseInt(a[1]) - Integer.parseInt(b[1]));
int time = 0;
if (Integer.parseInt(process[0][1]) > time) {
time = Integer.parseInt(process[0][1]);
}
if (Integer.parseInt(process[0][1])==Integer.parseInt(process[1][1])){
if (Integer.parseInt(process[0][2])>Integer.parseInt(process[1][2])) {
String[] temp = process[0];
process[0] = process[1];
process[1] = temp;
}
}
if (Integer.parseInt(process[0][1])==Integer.parseInt(process[1][1])&&Integer.parseInt(process[2][1])==Integer.parseInt(process[1][1])){
Arrays.sort(process,(a,b) -> Integer.parseInt(a[2]) - Integer.parseInt(b[2]));
}
time = time + Integer.parseInt(process[0][2]);
process[0][2]=String.valueOf(time-Integer.parseInt(process[0][1]));
if (time > Integer.parseInt(process[1][1]) && time > Integer.parseInt(process[2][1])) {
int waitTime1 =time - Integer.parseInt(process[1][1]) ;
int waitTime2 = time - Integer.parseInt(process[2][1]);
double ratio1 = waitTime1 / Double.parseDouble(process[1][2]);
double ratio2 = waitTime2 / Double.parseDouble(process[2][2]);
if (ratio1 < ratio2) {
String[] temp = process[1];
process[1] = process[2];
process[2] = temp;
}
} else if (time < Integer.parseInt(process[1][1]) && time < Integer.parseInt(process[2][1])) {
time = Integer.parseInt(process[1][1]);
}
time = time + Integer.parseInt(process[1][2]);
process[1][2]=String.valueOf(time-Integer.parseInt(process[1][1]));
if (time < Integer.parseInt(process[2][1])) {
time = Integer.parseInt(process[2][1]);
}
time = time + Integer.parseInt(process[2][2]);
process[2][2]=String.valueOf(time-Integer.parseInt(process[2][1]));
Arrays.sort(process,(a,b) -> a[0].compareTo(b[0]));
for (String[] strings : process) {
System.out.print(strings[2]+" ");
}
}
}
题目3:并发进程的分类—利用BERSTEIN条件判断语句的无关性与交互性
问题描述:要求输入两条赋值语句(赋值号为:=),且语句中仅仅有加减乘除运算,利用BERSTEIN条件判断语句的无关性与交互性。
输入格式:程序要求输入两行,以回车符号作为分隔,每一行即为一条语句。
输出格式:输出一个字符串。若为交互性语句则输出为”false”(不含双引号,所有字母皆为小写);若为无关性语句则输出”true”(不含双引号,所有字母皆为小写)。
样例输入1:
x:=m+n;
y:=2*k;
样例输出1:
true
样例输入2:
x:=m+n;
m:=2*k;
样例输出2:
false
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String s1 = sc.next();
String s2 = sc.next();
String x = s1.substring(0, 1);
String y = s2.substring(0, 1);
List<String> a = new ArrayList<>();
List<String> b = new ArrayList<>();
for (char c : s1.toCharArray()) {
if (c != '+' && c != '-' && c != '*' && c != '/') {
a.add(String.valueOf(c));
}
}
for (char c : s2.toCharArray()) {
if (c != '+' && c != '-' && c != '*' && c != '/') {
b.add(String.valueOf(c));
}
}
if (!x.equals(y) && !a.contains(y) && !b.contains(x)) {
System.out.print("true");
} else {
System.out.println("false");
}
sc.close();
}
}
题目4:死锁—利用银行家算法判断资源是否可以申请成功
问题描述:假设系统中有A、B、C三类资源,且有五个并发进程,要求输入当前系统可用资源量Available,以及每个进程运行所需的资源总量Claim、已经分配得到的资源量Allocation和进程的资源申请。利用银行家算法判断进程的资源申请能否得到系统的满足。
输入格式:程序要求输入七行,以回车符号作为分隔。第一行是三个整数,整数之间以空格作为分隔,表示当前系统可用的A、B、C三类资源量Available。下面的五行分别表示每个进程运行所需的资源总量Claim和已经分配得到的资源量Allocation;每行有7个数据,以空格作为分隔。首先输入一个字符串(长度小于等于10),为进程名;第2、3、4个数据类型为整型,表示相应进程运行所需A、B、C三种资源总量Claim;第5、6、7个数据类型为整型,表示相应进程已经分配得到的A、B、C三种资源量Allocation。第七行有4个数据,以空格作为分隔。首先输入一个字符串(长度小于等于10),为申请资源的进程名;第2、3、4个数据类型为整型,表示所申请A、B、C三种资源的量。
输出格式:输出一个字符串。若系统不能满足资源申请则输出为”false”(不含双引号,所有字母皆为小写);若系统可以满足资源申请则输出”true”(不含双引号,所有字母皆为小写)。
样例输入1:
3 3 2
P0 7 5 3 0 1 0
P1 3 2 2 2 0 0
P2 9 0 2 3 0 2
P3 2 2 2 2 1 1
P4 4 3 3 0 0 2
P1 1 0 2
样例输出1:
true
样例输入2:
3 3 2
P0 7 5 3 0 1 0
P1 3 2 2 2 0 0
P2 9 0 2 3 0 2
P3 2 2 2 2 1 1
P4 4 3 3 0 0 2
P4 3 4 0
样例输出2:
false
import java.util.HashMap;
import java.util.Scanner;
public class Main {
static int[] ava = new int[3];
static int[][] max = new int[5][3];
static int[][] all = new int[5][3];
static int[][] need = new int[5][3];
static int[] req = new int[3];
static boolean[] finish = new boolean[5];
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
HashMap<String, Integer> map = new HashMap<>();
for (int i = 0; i < 3; i++) {
ava[i] = sc.nextInt();
}
for (int i = 0; i < 5; i++) {
String name = sc.next();
for (int j = 0; j < 3; j++) {
max[i][j] = sc.nextInt();
}
for (int j = 0; j < 3; j++) {
all[i][j] = sc.nextInt();
}
need[i][0] = max[i][0] - all[i][0];
need[i][1] = max[i][1] - all[i][1];
need[i][2] = max[i][2] - all[i][2];
map.put(name, i);
}
int t = map.get(sc.next());
for (int i = 0; i < 3; i++) {
req[i] = sc.nextInt();
}
boolean flag = true;
for (int i = 0; i < 3; i++) {
if (req[i] > ava[i] || req[i] > need[t][i]) {
flag = false;
break;
}
}
if (!flag) {
System.out.print("false");
} else {
for (int i = 0; i < 3; i++) {
ava[i] -= req[i];
need[t][i] -= req[i];
all[t][i] += req[i];
}
while (true) {
boolean find = false;
for (int i = 0; i < 5; i++) {
if (!finish[i] && needLessOrEqual(ava, need[i])) {
finish[i] = true;
add(ava, all[i]);
find = true;
}
}
if (!find) {
break;
}
}
boolean allFinish = true;
for (int i = 0; i < 5; i++) {
if (!finish[i]) {
allFinish = false;
}
}
if (allFinish) {
System.out.print("true");
} else {
System.out.print("false");
}
}
}
public static boolean needLessOrEqual(int[] ava, int[] need) {
for (int i = 0; i < 3; i++) {
if (ava[i] < need[i]) {
return false;
}
}
return true;
}
public static void add(int[] dest, int[] src) {
for (int i = 0; i < 3; i++) {
dest[i] += src[i];
}
}
}
题目5:存储管理—可变分区存储管理方式的最佳适应、下次适应、最差适应分配算法
问题描述:当采用可变分区分配方案对1024KB的内存进行管理时,要求输入多个进程已经占用分区信息、一个进程内存请求以及所选用的分配算法,输出显示分配给进程的分区信息。
输入格式:程序要求输入4行,以回车符号作为分隔,第一行是一个整数n(4>n>0),表示进程已经占用分区的数量;第二行是2n个整数,依次按地址递增对应第一行n个进程已经占用分区的起始地址和存储容量(单位为KB)。第三行是三个整数,表示进程申请的内存空间大小(存储容量单位为KB);第四行是一个字符串,用”BEST”、 ”NEXT”、 ”WORST” (不含双引号,所有字母皆为大写)分别表示所选用的最佳适应、下次适应和最差适应分配算法。
输出格式:输出三个整数或字符串”false”(不含双引号,所有字母皆为小写),分别表示给进程所分配分区的起始地址;若某进程分配失败,则用”false”表示(不含双引号,所有字母皆为小写)。
样例输入1:
1
50 100
20 20 80
BEST
样例输出1:
0 20 150
样例输入2:
1
300 100
400 500 100
WORST
样例输出2:
400 false 0
#include <stdio.h>
int num = 0, idx = 0;
int A[10], B[10], space[3];
void best(int len) {
int size = len + 1;
int min = 1024;
int minQuality = 1024;
int isPos = 0;
for (int i = 0; i < size; i++) {
if (B[i] < minQuality && space[num] <= B[i]) {
min = i;
minQuality = B[i];
isPos = 1;
}
}
if (isPos == 0) {
printf("false ");
} else {
printf("%d ", A[min]);
A[min] += space[num];
B[min] -= space[num];
}
num++;
if (num == 3) {
return;
} else {
best(len);
}
}
void next(int len) {
int size = len + 1;
int i = idx;
do {
if (space[num] <= B[i]) {
idx = (i + 1) % size;
printf("%d ", A[i]);
A[i] += space[num];
B[i] -= space[num];
num++;
break;
}
i = (i + 1) % size;
} while (i != idx);
if (num == 3) {
return;
} else {
next(len);
}
}
void worst(int len) {
int size = len + 1;
int max = -1;
int maxQuality = -1;
int isPos = 0;
for (int i = 0; i < size; i++) {
if (B[i] > maxQuality && space[num] <= B[i]) {
max = i;
maxQuality = B[i];
isPos = 1;
}
}
if (isPos == 0) {
printf("false ");
} else {
printf("%d ", A[max]);
A[max] += space[num];
B[max] -= space[num];
}
num++;
if (num == 3) {
return;
} else {
worst(len);
}
}
int main() {
int n;
scanf("%d", &n);
int array[n][2];
A[0] = 0;
for (int i = 0; i < n; i++) {
scanf("%d %d", &array[i][0], &array[i][1]);
A[i + 1] = array[i][0] + array[i][1];
B[i] = array[i][0] - A[i];
if (i == n - 1) {
B[i + 1] = 1024 -A[i + 1];
}
}
for (int i = 0; i < 3; i++) {
scanf("%d", &space[i]);
}
char way[5];
scanf("%s", way);
switch(way[0]) {
case 'B':
best(n);
break;
case 'N':
next(n);
break;
case 'W':
worst(n);
break;
default:
break;
}
return 0;
}
题目6:存储管理—FIFO页面替换算法计算中断次数
问题描述:在请求分页式存储管理方式中,要求输入一个对5个页面的访问序列,输出当系统分配给进程物理页框数为m个时,按照FIFO页面替换算法的缺页中断次数(假设初始时页框均为空)。
输入格式:程序要求输入3行,以回车符号作为分隔,第一行是一个整数n,表示页面访问序列中访问页面的次数;第二行是n个整数,数之间以空格作为分隔,表示页面访问序列。第三行是一个整数m,表示系统分配给进程物理页框数。
输出格式:输出一个整数,表示缺页中断次数。
样例输入1:
12
4 3 2 1 4 3 5 4 3 2 1 5
3
样例输出1:
9
样例输入2:
12
4 3 2 1 4 3 5 4 3 2 1 5
4
样例输出2:
10
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef struct Node {
int item;
struct Node *next;
} Node;
typedef struct {
Node *head;
Node *last;
int N;
} Queue;
typedef struct {
Queue *queue;
Node *current;
} Iterator;
Iterator *iterator_init(Queue *queue) {
Iterator *iterator = (Iterator *)malloc(sizeof(Iterator));
iterator->queue = queue;
iterator->current = queue->head;
return iterator;
}
bool iterator_has_next(Iterator *iterator) {
return iterator->current->next != NULL;
}
bool queue_empty(Queue *queue) {
return queue->N == 0;
}
int queue_size(Queue *queue) {
return queue->N;
}
int iterator_next(Iterator *iterator) {
iterator->current = iterator->current->next;
return iterator->current->item;
}
int queue_dequeue(Queue *queue) {
if (queue_empty(queue)) {
return -1;
}
Node *old_first = queue->head->next;
int item = old_first->item;
queue->head->next = old_first->next;
queue->N--;
if (queue_empty(queue)) {
queue->last = NULL;
}
free(old_first);
return item;
}
void queue_init(Queue *queue) {
queue->head = (Node *)malloc(sizeof(Node));
queue->head->next = NULL;
queue->last = NULL;
queue->N = 0;
}
void queue_enqueue(Queue *queue, int item) {
if (queue->last == NULL) {
queue->last = (Node *)malloc(sizeof(Node));
queue->last->item = item;
queue->last->next = NULL;
queue->head->next = queue->last;
} else {
Node *old_last = queue->last;
queue->last = (Node *)malloc(sizeof(Node));
queue->last->item = item;
queue->last->next = NULL;
old_last->next = queue->last;
}
queue->N++;
}
int main() {
int result = 0;
int n;
scanf("%d", &n);
int *input = (int *)malloc(n * sizeof(int));
for (int i = 0; i < n; i++) {
scanf("%d", &input[i]);
}
int m;
scanf("%d", &m);
Queue *queue = (Queue *)malloc(sizeof(Queue));
queue_init(queue);
for (int i = 0; i < n; i++) {
bool flag = false;
Iterator *iterator = iterator_init(queue);
while (iterator_has_next(iterator)) {
if (iterator_next(iterator) == input[i]) {
flag = true;
break;
}
}
free(iterator);
if (!flag) {
result++;
if (queue_size(queue) < m) {
queue_enqueue(queue, input[i]);
} else {
queue_dequeue(queue);
queue_enqueue(queue, input[i]);
}
}
}
printf("%d", result);
free(input);
Node *current = queue->head->next;
while (current != NULL) {
Node *temp = current;
current = current->next;
free(temp);
}
free(queue->head);
free(queue);
return 0;
}
题目7:带存储管理的处理器调度4
问题描述:现有一个内存为100K的采用位示图进行页面管理的道数不受限制的多道程序设计系统,若作业调度采用高优先级(优先数越大优先级越大)调度算法(如果遇到优先级一样且只能调入一道作业时,按照输入顺序选择调度对象。),进程调度采用非剥夺式的SJF调度算法(如果遇到运行时间相同的进程,按照输入顺序选择调度对象。)。要求输入3个进程信息,输出当三个作业同时提交进入调度时进程的运行顺序。
输入格式:程序要求输入3行,以回车符号作为分隔,每行有4个数据,以空格作为分隔。首先输入一个字符串(长度小于等于10),为进程名;第2个数据类型为整型,表示进程所需的内存空间;第3个数据类型为整型,表示进程的运行时间;第4个数据类型为整型,表示进程的优先数。
输出格式:输出1行,M个字符串,字符串之间用空格作为分隔。
样例输入1:
P1 20 2 1
P2 60 3 2
P3 30 4 3
样例输出1:
P2 P1 P3
样例输入2:
P1 80 2 2
P2 30 5 3
P3 40 3 1
样例输出2:
P3 P2 P1
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String[][] pc = new String[3][4];
for (String[] arr : pc) {
arr[0] = sc.next();
arr[1] = String.valueOf(sc.nextInt());
arr[2] = String.valueOf(sc.nextInt());
arr[3] = String.valueOf(sc.nextInt());
}
List<String[]> list = new ArrayList<>();
compare(pc);
int count = 0;
while (!isFinish(pc)) {
if (count < 3) {
for (String[] arr : pc) {
if (!"0".equals(arr[2]) && ifenter(list, arr) && !list.contains(arr)) {
list.add(arr);
count++;
}
}
}
list.sort(Comparator.comparingInt(p -> Integer.parseInt(p[2])));
list.sort(Comparator.comparing(p -> p[0]));
String[] minElement = list.stream().min(Comparator.comparing(p -> Integer.parseInt(p[2]))).orElse(null);
if (minElement != null) {
for (int i = 0; i < 3; i++) {
if (minElement[0].equals(pc[i][0])) {
pc[i][2] = "0";
System.out.print(pc[i][0] + " ");
list.remove(minElement);
break;
}
}
}
}
}
public static void compare(String[][] pc) {
for (int i = 0; i < pc.length - 1; i++) {
for (int j = 0; j < pc.length - 1 - i; j++) {
if (Integer.parseInt(pc[j][3]) < Integer.parseInt(pc[j + 1][3])) {
String[] temp = pc[j];
pc[j] = pc[j + 1];
pc[j + 1] = temp;
} else if (Integer.parseInt(pc[j][3]) == Integer.parseInt(pc[j + 1][3])) {
if (pc[j][0].compareTo(pc[j + 1][0]) > 0) {
String[] temp = pc[j];
pc[j] = pc[j + 1];
pc[j + 1] = temp;
}
}
}
}
}
public static boolean isFinish(String[][] pc) {
for (String[] arr : pc) {
if (!"0".equals(arr[2])) {
return false;
}
}
return true;
}
public static boolean ifenter(List<String[]> list, String[] pc) {
int time = 0;
int max = 100;
for (String[] arr : list) {
time += Integer.parseInt(arr[1]);
}
return time + Integer.parseInt(pc[1]) <= max;
}
}
题目8:驱动调度—采用电梯调度算法排列出磁盘请求响应次序
问题描述:要求输入一个柱面访问请求序列以及当前磁头所在柱面号和移动方向,输出采用电梯调度算法时移动臂响应的柱面访问序列。
输入格式:程序要求输入3行,以回车符号作为分隔,第一行是2个整数n、m,之间用空格隔开,n表示当前磁头所在的柱面号;m表示第二行输入m个数;第二行是m个整数,数之间以空格作为分隔,表示柱面访问请求序列;第三行是数字-1或1,当为-1时表示移动臂向柱面号减小方向移动,当为1时表示移动臂向柱面号增大方向移动。
输出格式:输出m个整数,数之间以空格作为分隔,采用电梯调度算法时移动臂响应的柱面访问序列。
样例输入1:
15 10
24 38 2 110 43 36 5 11 6 180
-1
样例输出1:
11 6 5 2 24 36 38 43 110 180
样例输入2:
15 10
24 38 2 110 43 36 5 11 6 180
1
样例输出2:
24 36 38 43 110 180 11 6 5 2
#include<stdio.h>
void sort(int v[], int m);
void search(int v[],int arr[],int n,int d,int m);
int main(){
int n,m,d;
int arr[100]={0},v[100]={0};
scanf("%d%d",&n,&m);
for(int i = 0;i < m;i++) scanf("%d", &v[i]);
scanf("%d",&d);
sort(v,m);
search(v,arr,n,d,m);
for(int i = 0;i < m;i++) printf("%d ",arr[i]);
return 0;
}
void sort(int v[], int m){
int temp;
for(int i=0; i<m; i++){
for(int j=0; j<m-i-1; j++){
if(v[j]>v[j+1]){
temp = v[j+1];
v[j+1] = v[j];
v[j] = temp;
}
}
}
}
void search(int v[],int arr[],int n,int d,int m){
int temp2=0,r=0;
for(int i=0; i<m; i++){
if(v[i]>=n){
temp2 = i;
break;
}
}
if(d== -1){
for(int i=temp2-1; i>-1; i--){
arr[r] = v[i];
r++;
}
for(int j=temp2; j<m; j++){
arr[r] = v[j];
r++;
}
}
else{
for(int i=temp2; i<m; i++){
arr[r] = v[i];
r++;
}
for(int j=temp2-1; j>-1; j--){
arr[r] = v[j];
r++;
}
}
}