以前写的老代码参见这里,因为代码的结构很糟糕,而且有些人私信我能不能重写一下,遂重写了一下,从面向过程到面向对象,希望能对您有所帮助.
#pragma region 提示信息
/* Start by [Han.des].[2019/12/13]
1.该代码是对之前代码的一次重写和复习
2.磁盘调度算法FCFS,SSTF,SCAN,CSCAN,NstepSCAN算法
3.计算性能
End */
#pragma endregion
#include
#include
#include
#include
using namespace std;
class DiskScheduling {
public:
DiskScheduling() :DiskScheduling(10, 0, 200) {}
DiskScheduling(int diskNum, int startPos, int maxPos) {
uniform_int_distribution<unsigned> u(0, maxPos);
default_random_engine e(10);
while (diskNum--) {
diskInputSeq.push_back(u(e));
}
diskStartPos = startPos;
diskMaxPos = maxPos;
}
DiskScheduling(vector<int>& diskInput) {
diskMaxPos = *max_element(diskInput.begin(), diskInput.end());
diskStartPos = 0;
diskInputSeq = diskInput;
}
DiskScheduling(vector<int>& diskInput, int startPos, int maxPos) {
diskMaxPos = maxPos;
diskStartPos = startPos;
diskInputSeq = diskInput;
}
void FCFS() {
diskOutputSeq = diskInputSeq;
for (auto i = diskInputSeq.begin(); i != diskInputSeq.end() - 1; ++i) {
sumStep += abs(*i - *(i + 1));
}
sumStep += abs(diskStartPos - diskInputSeq[0]);
cout << "\t\tFCFS算法\t\t\n";
Print();
Reset();
}
void SSTF() {
vector<int> diskTemp(diskInputSeq);
int diskStartTemp = diskStartPos;
int count = diskTemp.size();
while (count--) {
auto minNow = min_element(diskTemp.begin(), diskTemp.end(), [diskStartTemp](const int& first, const int& second) {
return abs(diskStartTemp - first) < abs(diskStartTemp - second);
});
diskOutputSeq.push_back(*minNow);
sumStep += abs(diskStartTemp - *minNow);
diskStartTemp = *minNow;
*minNow = INT_MAX;
}
cout << "\t\tSSTF算法\t\t\n";
Print();
Reset();
}
// dir = true 移动方向为磁盘号小到大的方向
void SCAN(bool dir = true) {
ScanCscanHelper(dir, 0);
cout << "\t\tSCAN算法\t\t\n";
Print();
Reset();
}
void CSCAN(bool dir = true) {
ScanCscanHelper(dir, 1);
cout << "\t\tCSCAN算法\t\t\n";
Print();
Reset();
}
void NstepSCAN(int nGroup, bool dir = true) {
int diskStartTemp = diskStartPos;
vector<int> diskTemp;
int groupSize = (int)ceil(diskInputSeq.size() / (double)nGroup);
for (auto i = diskInputSeq.begin(); i != diskInputSeq.end(); i += groupSize) {
if (diskInputSeq.end() - i < groupSize)
diskTemp.assign(i, diskInputSeq.end()), i = diskInputSeq.end()-groupSize;
else
diskTemp.assign(i, i + groupSize);
DiskScheduling diskT(diskTemp, diskStartTemp, diskMaxPos);
diskT.ScanCscanHelper(dir, 0);
sumStep += diskT.getSumStep();
vector<int> diskOutputGroup = diskT.getDiskOutputSeq();
diskStartTemp = *diskOutputGroup.rbegin();
diskOutputSeq.insert(diskOutputSeq.end(),diskOutputGroup.begin(),diskOutputGroup.end());
}
cout << "\t\tNstepSCAN\t\t\n";
Print();
Reset();
}
void ScanCscanHelper(int dir, int opt) {
vector<int> diskTemp(diskInputSeq);
sort(diskTemp.begin(), diskTemp.end(), [dir](const int& first, const int& second) {
return dir ? first > second: first < second;
});
auto i = diskTemp.begin();
for (; i != diskTemp.end() - 1; i++) {
if ((*i - diskStartPos) * (*(i + 1) - diskStartPos) <= 0) {
if ((*(i + 1) - diskStartPos) == 0) i++;
break;
}
}
reverse(diskTemp.begin(), i + 1);
if (opt == 1) reverse(i + 1, diskTemp.end());
diskOutputSeq = diskTemp;
for (auto j = diskOutputSeq.begin(); j != diskOutputSeq.end() - 1; ++j) {
sumStep += abs(*j - *(j + 1));
}
sumStep += abs(diskStartPos - diskOutputSeq[0]);
}
int getSumStep() { return sumStep; }
vector<int> getDiskOutputSeq() { return diskOutputSeq; }
private:
void Print() {
cout << "起始磁道号\t" << diskStartPos << endl;
cout << "最大磁道号\t" << diskMaxPos << endl;
cout << "磁道待访问顺序\t\n";
for (int diskNow : diskInputSeq)
cout << diskNow << " ";
cout << "\n磁道实际访问顺序\t\n";
for (int diskActual : diskOutputSeq)
cout << diskActual << " ";
cout << "\n移动的磁道总数\t" << sumStep << endl;
cout << "平均寻道数\t" << sumStep / diskOutputSeq.size() << "\n\n\n";
}
void Reset() {
sumStep = 0;
diskOutputSeq.clear();
}
private:
int diskStartPos; // 起始的磁道号 or 磁盘机械臂当前位置
int diskMaxPos; // 最大的磁道号
double sumStep = 0; // 访问的总步数
vector<int> diskInputSeq; // 磁道待访问顺序
vector<int> diskOutputSeq; // 磁道实际的访问顺序
};
int main() {
DiskScheduling disk1(40,104,200);
disk1.FCFS();
disk1.SSTF();
disk1.SCAN(false);
disk1.CSCAN(false);
disk1.NstepSCAN(3);
return 0;
}
大概花了2个多小时做完了这个工作,因为这块的内容也忘了,所以需要复习复习,算法本身难度并不大,写出可读性强的代码应该是2.0版本的诉求,摒弃了部分不太好的用法,同时比以前的更加友好,虽然仍有部分地方偷懒了,比如NstepScan算法中.如果有什么建议和想法,欢迎评论区留言或者私信我.