根據隊列和棧的性質
隊列找尾部最大的車廂號
棧找尾部最小的車廂號
棧、隊列、數組可用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);
}