磁盘调度算法的C++实现2.0 (FCFS、SSTF、SCAN、CSCAN、NStepSCAN)

磁盘调度算法的C++实现2.0 (FCFS、SSTF、SCAN、CSCAN、NStepSCAN)

前言

以前写的老代码参见这里,因为代码的结构很糟糕,而且有些人私信我能不能重写一下,遂重写了一下,从面向过程到面向对象,希望能对您有所帮助.

代码

#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算法中.如果有什么建议和想法,欢迎评论区留言或者私信我.

你可能感兴趣的:(SchoolDays)