車廂調度問題(隊列和棧的實現)

根據隊列和棧的性質

隊列找尾部最大的車廂號

棧找尾部最小的車廂號

棧、隊列、數組可用STL或者自己實現

#pragma once
#include "vector.h"
#include "queue.h"
#include "stack.h"
#include <fstream>

const char* INPUTVECTORFILENAME = "carriagesRearrangement.txt";
const char* RESULTFILE = "carriagesResult.txt";

template<class T>
const int calculateK(Vector<T> & v) {
	int k = 0;
	for (int i = 1; i < v.size(); ++i) {
		if (v[i] < v[i - 1]) {
			k++;
		}
	}
	return k;
}

void generateTestData(const char* fileName, const int &n) {
	std::ofstream fout(fileName);
	if (fout.is_open()) {
		int *a = new int[n];
		for (int i = 0; i < n; ++i) {
			a[i] = i + 1;
		}
		for (int i = 0; i < n; ++i) {
			std::swap(a[i], a[rand() % n]);
		}
		for (int i = 0; i < n; ++i) {
			fout << a[i] << ' ';
		}
		fout.close();
	}
}

template<class T>
void inputVectorFromFile(Vector<T> & v, const char* fileName) {
	std::ifstream fin(fileName);
	if (fin.is_open()) {
		T temp;
		while (fin >> temp) {
			v.push_back(temp);
		}
		v.reverse();
		fin.close();
	}
}

Vector<int> carriagesRearrangement_queue(Vector<int> &carriages, const int k, const char* fileName) {
	std::ofstream fout(fileName);
	if (fout.is_open()) {
		if (k == 0) {
			return carriages;
		}
		Queue<int> *buffer = new Queue<int>[k]; // 緩衝車廂
		Vector<int> arrangedCarriages; // 排序後的車廂
		arrangedCarriages.push_back(0); // 加入一個頭節點
		// i和j用於循環
		int i = NULL, j = NULL;
		// n記錄車廂總長
		int n = carriages.size();
		// temp記錄第i節車廂
		int temp = NULL;
		// max和tag記錄最大的車廂及其編號
		int max = NULL, tag = NULL;
		for (i = 0; i < n; ++i) {
			temp = carriages[i];
			// 如果當前車廂的編號等於排序後的車廂尾部編號的下一個,就直接加入到排序後車廂
			if (arrangedCarriages.back() + 1 == temp) {
				arrangedCarriages.push_back(temp);
				fout << "carriage " << temp << " move to the track from carriages\n";
				continue;
			}
			max = 0;
			tag = 0;
			/*
			 *如果不滿足上面的條件
			 *在尾部車廂號最大的車廂後面插入
			 *否則找一個新的緩衝軌插入
			 */
			for (j = 0; j < k; ++j) {
				// 找到空的緩衝鐵軌時判斷
				if (buffer[j].empty() || k - 1 == j) {
					if (0 == max) {
						buffer[j].enQueue(temp);
						fout << "carriage " << temp << " move to the buffer " << j + 1 << " from carriages\n";
						break;
					}
					else {
						buffer[tag].enQueue(temp);
						fout << "carriage " << temp << " move to the buffer " << tag + 1 << " from carriages\n";
						break;
					}
				}
				// 用來找比當前車廂號大的最大車廂號
				if (buffer[j].back() < temp) {
					if (buffer[j].back() > max) {
						max = buffer[j].back();
						tag = j;
					}
				}
			}
		}
		bool correctTag = false;
		// 退隊過程
		while (arrangedCarriages.size() <= n) {
			for (i = 0; i < k; ++i) {
				correctTag = false;
				if (!buffer[i].empty() && buffer[i].front() == arrangedCarriages.back() + 1) {
					arrangedCarriages.push_back(buffer[i].front());
					fout << "carriage " << buffer[i].front() << " move to the track from buffer " << i + 1 << '\n';
					buffer[i].deQueue();
					correctTag = true;
					break;
				}
			}
			if (!correctTag) {
				fout << "wrong!";
				return carriages;
			}
		}
		arrangedCarriages.erase(0); // 刪除頭節點
		fout.close();
		return arrangedCarriages.reverse();
	}
	return carriages;
}

Vector<int> carriagesRearrangement_stack(Vector<int> &carriages, const int k, const char* fileName) {
	std::ofstream fout(fileName);
	if (fout.is_open()) {
		if (k == 0) {
			return carriages;
		}
		Stack<int> *buffer = new Stack<int>[k]; // 緩衝車廂
		Vector<int> arrangedCarriages; // 排序後的車廂
		arrangedCarriages.push_back(0); // 加入一個頭節點
		// i和j用於循環
		int i = NULL, j = NULL;
		// n記錄車廂總長
		int n = carriages.size();
		// temp記錄第i節車廂
		int temp = NULL;
		// min和tag記錄最小的車廂及其編號
		int min = NULL, tag = NULL;
		for (i = 0; i < n; ++i) {
			temp = carriages[i];
			// 如果當前車廂的編號等於排序後的車廂尾部編號的下一個,就直接加入到排序後車廂
			if (arrangedCarriages.back() + 1 == temp) {
				arrangedCarriages.push_back(temp);
				fout << "carriage " << temp << " move to the track from carriages\n";
				continue;
			}
			min = n + 1;
			tag = 0;
			/*
			 *如果不滿足上面的條件
			 *在尾部車廂號最小的車廂後面壓入
			 *否則找一個新的緩衝軌壓入
			 */
			for (j = 0; j < k; ++j) {
				// 找到空的緩衝鐵軌時判斷
				if (buffer[j].empty() || k - 1 == j) {
					if (n + 1 == min) {
						buffer[j].push(temp);
						fout << "carriage " << temp << " move to the buffer " << j + 1 << " from carriages\n";
						break;
					}
					else {
						buffer[tag].push(temp);
						fout << "carriage " << temp << " move to the buffer " << tag + 1 << " from carriages\n";
						break;
					}
				}
				// 用來找比當前車廂號小的最小車廂號
				if (temp < buffer[j].top()) {
					if (buffer[j].top() < min) {
						min = buffer[j].top();
						tag = j;
					}
				}
			}
		}
		bool correctTag = false;
		// 出棧過程
		while (arrangedCarriages.size() <= n) {
			for (i = 0; i < k; ++i) {
				correctTag = false;
				if (!buffer[i].empty() && buffer[i].top() == arrangedCarriages.back() + 1) {
					arrangedCarriages.push_back(buffer[i].top());
					fout << "carriage " << buffer[i].top() << " move to the track from buffer " << i + 1 << '\n';
					buffer[i].pop();
					correctTag = true;
					break;
				}
			}
			if (!correctTag) {
				fout << "something wrong!";
				return carriages;
			}
		}
		arrangedCarriages.erase(0); // 刪除頭節點
		fout.close();
		return arrangedCarriages.reverse();
	}
	return carriages;
}

void carriagesTest() {
	Vector<int> v;
	int n = 20;
	generateTestData(INPUTVECTORFILENAME, n);
	inputVectorFromFile(v, INPUTVECTORFILENAME);
	v = carriagesRearrangement_stack(v, calculateK(v), RESULTFILE);
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章