一、实验目的
二、实验类型
综合性实验。综合高级语言、数据结构、磁盘管理模型等多方面的知识
三、实验选题
设计一个磁盘调度管理方案。并编写模拟程序实现之。产生一个需要访问的指令地址流。它是一系列需要访问的磁盘地址。为不失一般性,你可以适当地(用人工指定地方法或用随机数产生器)生成这个序列,使得 50%的指令是顺序执行的。25%的指令均匀地散布在前地址部分,25%的地址是均匀地散布在后地址部分。
磁盘算法:FIFO、最短时间算法、单向扫描算法、双向扫描算法、电梯算法
话不多说,上代码
#include
#include
#include
#include
using namespace std;
int data[100] = {0};
int data_number = 0;
bool compare(int a, int b) {
return a < b; // 升序排列,如果改为return a>b ,则为降序
}
int FCFS() {
int cnt = 0;
cout << "访问序列为:";
for (int i = 0; i < data_number - 1; i++) {
cout << data[i] << " ";
cnt += abs(data[i] - data[i + 1]);
}
cout << data[data_number - 1] << endl;
cout << "总的移动次数为:" << cnt << endl;
return cnt;
}
int SSTF() {
int tmp, m, i = 0;
int cnt = 0;
int done = 1; //记录遍历的柱面个数
cout << "访问序列为:" << data[0] << " ";
//遍历每一个柱面
while (done < data_number) {
//初始化第一个差值
for (int j = 0; j < data_number; j++) {
if(j != i && data[j] != -1) {
m = j;
tmp = abs(data[i] - data[m]);
break;
}
}
//比较其他差值
for (int j = 0; j < data_number; j++) {
if (j != i && data[j] != -1 && abs(data[i] - data[j]) < tmp) {
m = j;
tmp = abs(data[i] - data[m]);
}
}
cout << data[m] << " ";
cnt += abs(data[i] - data[m]);
done++;
data[i] = -1;
i = m;
}
cout << endl;
cout << "总的移动次数为:" << cnt << endl;
return cnt;
}
int CSCAN() { //单向扫描调度
int tmp = data[0];
int cnt = 0;
sort(data, data + data_number, compare);
int i;
for (i = 0; i < data_number; i++) { //for循环作用为find函数
if (data[i] == tmp) {
tmp = i;
break; // 停止循环
}
}
cout << "访问序列为:" << data[tmp] << " ";
//第一轮单向遍历
cnt += data[tmp]; //0到第一个柱面
while(i < data_number - 1){ //i后面还有柱面
cnt += data[i + 1] - data[i];
i++;
cout << data[i] << " ";
}
if(tmp != 0) {
cnt += data[i]; //回到0
cnt += data[0]; //0到data[0]
i = 0;
cout << data[i] << " ";
while(i < tmp - 1){ //从data[0]到data[tmp]
cnt += data[i + 1] - data[i];
i++;
cout << data[i] << " ";
}
}
cout << endl << "总的移动次数为:" << cnt << endl;
return cnt;
}
int bidirectional_scan(){ //双向扫描调度
int tmp = data[0];
int cnt = 0;
sort(data, data + data_number, compare);
int i;
for (i = 0; i < data_number; i++) { //for循环作用为find函数
if (data[i] == tmp) {
tmp = i;
break; // 停止循环
}
}
cout << "访问序列为:" << data[tmp] << " ";
//第一轮单向遍历
cnt += data[tmp]; //0到第一个柱面
while(i < data_number - 1){ //i后面还有柱面
cnt += data[i + 1] - data[i];
i++;
cout << data[i] << " ";
}
if(tmp != 0) {
cnt += data[i] - data[0];
i = tmp - 1;
for(; i >= 0; i--){
cout << data[i] << " ";
}
}
cout << endl << "总的移动次数为:" << cnt << endl;
return cnt;
}
int SCAN(){ //电梯调度
int choose, i, cnt = 0, tmp = data[0];
sort(data, data + data_number, compare);
for (i = 0; i < data_number; i++) { //for循环作用为find函数
if (data[i] == tmp) {
tmp = i;
break; // 停止循环
}
}
sign:
cout << "第一轮是向内还是向外: 1. 向内遍历 2. 向外遍历" << endl;
cin >> choose;
switch (choose) {
case 1:
for(i = tmp; i < data_number; i++){
cout << data[i] << " ";
}
cnt += data[data_number - 1] - data[tmp];
if(tmp != 0) {
for (i = tmp - 1; i >= 0; i--) {
cout << data[i] << " ";
}
cnt += data[data_number - 1] - data[0];
}
break;
case 2:
for(i = tmp; i >= 0; i--){
cout << data[i] << " ";
}
cnt += data[tmp] - data[0];
if(tmp != data_number - 1) {
for (i = tmp + 1; i < data_number; i++) {
cout << data[i] << " ";
}
cnt += data[data_number - 1] - data[0];
}
break;
default:
cout << "输入错误,请再输一遍。";
goto sign;
}
cout << endl << "总的移动次数为:" << cnt << endl;
return cnt;
}
void menu() {
cout << endl;
cout << "************************************************************************" << endl;
cout << " 磁盘管理算法 " << endl;
input();
cout << " 1. FCFS 2. SSTF 3. 单向扫描调度 " << endl;
cout << " 4. 双向扫描调度 5. 电梯调度 6. 退出程序 " << endl;
int choose;
recin:
cin >> choose;
switch (choose) {
case 1:
FCFS();
break;
case 2:
SSTF();
break;
case 3:
CSCAN();
break;
case 4:
bidirectional_scan();
break;
case 5:
SCAN();
break;
case 6:
cout << "程序正常结束,欢迎再次使用。";
exit(-1);
default:
cout << "输入错误,请重新输入。" << endl;
goto recin;
}
}
void input() {
int choose;
int number_of_Cylinders; //只有1和2情况有用到此变量
cout << "请选择输入数据的方式: 1. 手动输入 2. 随机生成 3. 文件读取" << endl;
cin >> choose;
switch (choose) {
case 1:
cout << "请输入柱面数目:";
cin >> number_of_Cylinders;
cout << "请输入柱面号的数目:";
cin >> data_number;
cout << "请依次输入柱面号:";
for (int i = 0; i < data_number; i++) {
cin >> data[i];
if (data[i] >= number_of_Cylinders) {
cout << "柱面号超出范围,请重新输入。" << endl;
i--;
}
}
break;
case 2:
cout << "请输入柱面数目:";
cin >> number_of_Cylinders;
cout << "请输入柱面号的数目:";
cin >> data_number;
srand((int) time(0)); // 产生随机种子 把0换成NULL也行
for (int i = 0; i < data_number; i++) {
data[i] = rand() % number_of_Cylinders;
}
break;
case 3:
read_file();
break;
}
cout << "输入的序列为:";
for (int i = 0; i < data_number; i++) {
cout << " " << data[i];
}
cout << endl;
}
void read_file() {
FILE *fp = fopen("C:\\Users\\Louisthecat\\Desktop\\project\\CLion_files\\exp7\\data.txt", "r");
if (fp == NULL) {
printf("文件读取无效。\n");
return;
}
int i;
for (i = 0; !feof(fp); i++)
fscanf(fp, "%d", &data[i]);
data_number = i;
cout << endl;
}
int main() {
while (true)
menu();
}
53 98 183 37 122 14 124 65 67