#ifndef _STACK_
#define _STACK_
//堆
template<class T> class CStack
{
public:
CStack()
{
this->capacity = 0;
this->top = -1;
this->data = NULL;
};
CStack(int size)
{
this->capacity = size;
this->top = -1;
this->data = new T[size];
}
~CStack()
{
if (data != NULL)
{
delete[] data;
data = NULL;
}
}
public:
inline void resize(int size)
{
if (data != NULL)
{
delete[] data;
data = NULL;
}
this->capacity = size;
this->top = -1;
this->data = new T[size];
}
inline bool empty()
{
return top==-1;
}
inline bool full()
{
return top == capacity-1;
}
inline T pop()
{
assert(top>=0, "no data");
return this->data[top--];
}
inline T peek()
{
assert(top>=0, "no data");
return this->data[top];
}
inline void push(T data)
{
assert(top < capacity-1, "space full");
this->data[++top] = data;
}
inline int size()
{
return top+1;
}
template<class T> friend ostream& operator<<(ostream &os,const CStack<T>& stack);
//template<class T> friend ostream& operator<<(ostream &os,const CStack<T>& stack);
public:
int capacity, top;//指向堆栈大小和栈头位置
T* data;
};
template<class T> ostream& operator<<(ostream &os,const CStack<T>& stack)
{
for (int index=0; index<=stack.top; index++)
{
os<<stack.data[index]<<" ";
}
cout<<endl;
return os;
}
#endif
#ifndef _QUEUE_
#define _QUEUE_
//队列
template<class T> class CQueue
{
public:
CQueue()
{
this->capacity = 0;
this->front = this->back = 0;
this->data = NULL;
};
CQueue(int size)
{
this->capacity = size;
this->front = this->back = 0;
this->data = new T[size];
}
~CQueue()
{
if (data != NULL)
{
delete[] data;
data = NULL;
}
}
public:
inline void resize(int size)
{
if (data != NULL)
{
delete[] data;
data = NULL;
}
this->capacity = size;
this->front = this->back = 0;
this->data = new T[size];
}
inline bool empty()
{
return front == back;
}
inline bool full()
{
return front == capacity-1;
}
inline T dequeue()
{
assert(front > back,"no data");
return this->data[back++];
}
inline T backpeek()
{
assert(front > back,"no data");
return this->data[back];
}
inline T frontpeek()
{
assert(front > back,"no data");
return this->data[front-1];
}
inline void enqueue(T data)
{
assert(front < capacity-1,"space full");
this->data[front++] = data;
}
inline int size()
{
return front-size;
}
template<class T> friend ostream& operator<<(ostream &os,const CQueue<T>& queue);
public:
int capacity, front, back;//指向队列大小和栈头位置
T* data;
};
template<class T> ostream& operator<<(ostream &os,const CQueue<T>& queue)
{
for (int index=queue.back; index<queue.front; index++)
{
os<<queue.data[index]<<" ";
}
cout<<endl;
return os;
}
#endif
#ifndef _CIRCLE_QUEUE_
#define _CIRCLE_QUEUE_
//循环队列
template<class T> class CCircleQueue
{
public:
CCircleQueue()
{
this->capacity = 0;
this->count = 0
this->front = this->back = 0;
this->data = NULL;
};
CCircleQueue(int size)
{
this->capacity = size;
this->count = 0;
this->front = this->back = 0;
this->data = new T[size];
}
~CCircleQueue()
{
if (data != NULL)
{
delete[] data;
data = NULL;
}
}
public:
inline bool empty()
{
return count == 0;
}
inline bool full()
{
return count == capacity-1;
}
inline T dequeue()
{
assert(count != 0,"space empty");
count--;
T tmp = this->data[back];
back = (back+1)%capacity;
return tmp;
}
inline T enqueue(T data)
{
assert(cout != capacity-1,"space full");
count++;
this->data[front] = data;
front = (front+1)%capacity;
}
inline int size()
{
return front-size;
}
template<class T> friend ostream& operator<<(ostream &os,const CCircleQueue<T>& queue);
public:
int capacity; //循环队列容量
int front; //
int back; //
int count; //循环队列数据量
T* data; //
};
template<class T> ostream& operator<<(ostream &os,const CCircleQueue<T>& queue)
{
for (int index= 0; index<= queue.count; index++)
{
os<<queue.data[(queue.back + index)%queue.capacity]<<" ";
}
cout<<endl;
return os;
}
#endif
#ifndef _FACTORY_SIMULATION
#define _FACTORY_SIMULATION
//工作调度中机器
class CMachine
{
public:
CMachine()
{
this->switchtime = 0;
};
CMachine(int switchtime)
{
this->switchtime = switchtime;
}
~CMachine(){}
public:
int switchtime; //机器切换时间
};
class CTask
{
public:
CTask()
{
this->producenum = 0;
this->curproduce = 0;
this->machineno = NULL;
this->worktime = NULL;
};
CTask(int producenum, int* machineno, int* worktime)
{
this->producenum = producenum;
this->curproduce = 0;
this->machineno = new int[producenum];
memcpy(this->machineno, machineno, sizeof(int)*producenum);
this->worktime = new int[producenum];
memcpy(this->worktime, worktime, sizeof(int)*producenum);
}
~CTask()
{
if (this->machineno != NULL)
{
delete[] this->machineno;
this->machineno = NULL;
}
if (this->worktime != NULL)
{
delete[] this->worktime;
this->worktime = NULL;
}
}
public:
int producenum; //工序数
int curproduce; //当前工序数
int* machineno; //需要哪些机器处理
int* worktime; //对应机器的处理时间
};
#endif
#include <iostream>
#include <assert.h>
#include "stack.h"
#include "queue.h"
#include "circlequeue.h"
#include "point.h"
#include "factorysimulation.h"
using namespace std;
template<class T> class CStackQueue
{
private :
CStackQueue(){} // 必须定义, 且为private.
CStackQueue(const CStackQueue&); // 不实现.
CStackQueue& operator=(const CStackQueue&); // 不实现.
~CStackQueue(){} // 可声明为public, 但这里声明为private没有错, 可被调用.
public :
static CStackQueue& GetInstance()
{
static CStackQueue theSingleton;
return theSingleton;
}
public :
//括号匹配,即左右括号进行匹配,可以对三种括号进行匹配({[
void BracketMatching_Stack(T *expr);
//汉诺塔是递归算法里的一个经典案例,有三根柱子A,B,C,A柱子上有N个盘子,从小到大依次叠放,
//要求把A上的盘子都移到C上,B可以作为临时存放,移动的时候必须始终遵循小盘子在大盘子上面,
//且每次只能移动一个盘子,求其算法。
//如果n=1,则将圆盘从A直接移动到C。
//如果n=2,则:
// (1)将A上的n-1(等于1)个圆盘移到B上;
// (2)再将A上的一个圆盘移到C上;
// (3)最后将B上的n-1(等于1)个圆盘移到C上。
//如果n=3,则:
// A)将A上的n-1(等于2,令其为n`)个圆盘移到B(借助于C),步骤如下:
// (1)将A上的n`-1(等于1)个圆盘移到C上。
// (2)将A上的一个圆盘移到B。
// (3)将C上的n`-1(等于1)个圆盘移到B。
// B)将A上的一个圆盘移到C。
// C)将B上的n-1(等于2,令其为n`)个圆盘移到C(借助A),步骤如下:
// (1)将B上的n`-1(等于1)个圆盘移到A。
// (2)将B上的一个盘子移到C。
// (3)将A上的n`-1(等于1)个圆盘移到C。到此,完成了三个圆盘的移动过程。
//从上面分析可以看出,当n大于等于2时, 移动的过程可分解为三个步骤:
//第一步 把A上的n-1个圆盘移到B上;
//第二步 把A上的一个圆盘移到C上;
//第三步 把B上的n-1个圆盘移到C上;
//其中第一步和第三步是类同的。
//当n=3时,第一步和第三步又分解为类同的三步,即把n`-1个圆盘从一个针移到另一个针上,这里的n`=n-1。
//将盘子从上到下进行编号,1,2,3......
void Hanio_Recursion(int n, T A, T B, T C);
//后来一位美国学者发现一种出人意料的简单方法,只要轮流进行两步操作就可以了。
//首先把三根柱子按顺序排成品字型,把所有的圆盘按从大到小的顺序放在柱子A上,根据圆盘的数量确定柱子的排放顺序:
//若n为偶数,按顺时针方向依次摆放 A B C;
//若n为奇数,按顺时针方向依次摆放 A C B。
//(1)按顺时针方向把圆盘1从现在的柱子移动到下一根柱子,
// 即当n为偶数时,若圆盘1在柱子A,则把它移动到B;若圆盘1在柱子B,则把它移动到C;若圆盘1在柱子C,则把它移动到A。
//(2)接着,把另外两根柱子上可以移动的圆盘移动到新的柱子上。
// 即把非空柱子上的圆盘移动到空柱子上,
// 当两根柱子都非空时,移动较小的圆盘。
// 这一步没有明确规定移动哪个圆盘,你可能以为会有多种可能性,其实不然,可实施的行动是唯一的。
//(3)反复进行(1)(2)操作,最后就能按规定完成汉诺塔的移动。
void Hanio_Unrecursion_Stack(int n);
//火车厢重排
//一列货运列车共有n节车厢,每节车厢将停放在不同的车站。假定n个车站的编号分别为1~n,
//即货运列车按照第n 站至第1站的次序经过这些车站。为了便于从列车上卸掉相应的车厢,
//车厢的编号应与车站(目的地)的编号相同,使各车厢从前至后按编号1到n的次序排列,
//这样,在每个车站只需卸掉最后一节车厢即可。所以,给定任意次序的车厢,必须重新排列它们。
//可能通过转轨站完成车厢的重排工作,在转轨站中有一个入轨、一个出轨和k个缓冲轨,缓冲轨位于入轨和出轨之间。
void Rail_Rearrangement_Stack(T *data, int n, int k);
void Rail_Rearrangement_Queue(T *data, int n, int k);
//给定一个矩形布线区域,其外围有若干针脚。两个针脚之间通过布设一条金属线路而实现互连。
//这条线路被称为电线,被限制在矩形区域内。如果两条电线发生交叉,则会发生电流短路。
//所以,不允许电线间的交叉。每对互连的针脚称为网组。现要求设计一个算法来确定:
//对于给定的网组,能否合理地布设电线以使其不发生交叉。
//为了解决开关盒布线问题,我们注意到,当两个针脚互连时,其电线把布线区分成两个分区
//为此,可以从一个分区中取出一个网组,利用该网组把这个分区又分成两个子分区,
//如果任一个网组的两个针脚都分布在同一个子分区之中(即不会出现两个针脚分别位于两个子分区的情形),
//那么这个分区就是可布线的。
void Switch_Box_Wiring_Stack(T *net, int n);
//离线等价类
//这个问题的输入是元素数目n、关系数目r 以及r 对关系,问题的目标是把n个元素分配至相应的等价类。
void Offline_Equivalent_Class_Stack(T *data, int n, T *datapair, int npair);
//迷宫老鼠
//外围补1
//右下左上一次寻找
//找到则入栈,同时更新路径,下一个节点重新找
//没找到则出栈,并从上一步的下一个方向开始寻找
//0记录可以走的点,1记录不能走的以及走过的,2记录最后行走路径
void FindPath_MouseMaze_Stack(T *maze, int rows, int cols);
//使用队列可以找到最短的路径,而堆栈做不到
//使用步数累加法,即从入口开始,可以走的点累加1,
//为了找到网格中位置a和b之间的最短路径,先从位置a 开始搜索,把a 可到达的相邻方格都标记为1(表示与a 相距为1),
//然后把标号为1的方格可到达的相邻方格都标记为2(表示与a相距为2),
//继续进行下去,直到到达b或者找不到可到达的相邻方格为止。
//为了不和堆栈混淆,入口初始点标记为10;
void FindPath_MouseMaze_Queue(T *maze, int rows, int cols);
//在单色图像中,每个像素的值要么为0,要么为1,值为0的像素表示图像的背景,
//而值为1的像素则表示图元上的一个点,我们称其为图元像素。
//如果一个像素在另一个像素的左侧、上部、右侧或下部,则称这两个像素为相邻像素。
//识别图元就是对图元像素进行标记,当且仅当两个像素属于同一图元时,它们的标号相同。
//注意,此处和迷宫不一样,1作为图元元素,则外围补一圈0,而非1
void Identity_Map_Queue(T *map, int rows, int cols);
//工厂仿真
//一项任务中的各道工序必须按照一定的次序来执行。
//一项任务的执行是从处理第一道工序的机器开始的,当第一道工序完成后,任务转至处理第二道工序的机器,
//依此进行下去,直到最后一道工序完成为止。当一项任务到达一台机器时,若机器正忙,则该任务将不得不等待。
//事实上,很可能有多项任务同时在同一台机器旁等待。
//在工厂中每台机器都可以有如下三种状态:活动、空闲和转换。
//在活动状态,机器正在处理一道工序,
//而在空闲状态机器无事可做。
//在转换状态,机器刚刚完成一道工序,并在为一项 新任务的执行做准备,比如机器操作员可能需要清理机器并稍作休息等。每台
//机器在转换状态期间所花费的时间可能各不相同。
//假定所有四项任务都在0时刻出现并且在仿真期间不再有新的任务出现。仿真过程一直持续到所有任务都已完成为止。
void Factory_Simulation_Queue(CMachine* Machine, int machinenum, CTask* Task, int tasknum);
private:
void OutBufferReset_Stack(int& minRailNo, int& minRailNoBuffer, CStack<T> *buffer, int k, int n);
bool HoldBufferReset_Stack(T data, int& minRailNo, int& minRailNoBuffer, CStack<T> *buffer, int k, int n);
void OutBufferReset_Queue(int& minRailNo, int& minRailNoBuffer, CQueue<T> *buffer, int k, int n);
bool HoldBufferReset_Queue(T data, int& minRailNo, int& minRailNoBuffer, CQueue<T> *buffer, int k, int n);
};
template<class T> void CStackQueue<T>::OutBufferReset_Stack(int& minRailNo, int& minRailNoBuffer, CStack<T> *buffer, int k,
int n)
{
buffer[minRailNoBuffer].pop();
cout<<"Move rail "<<minRailNo<<" from holding track "<<minRailNoBuffer+1<<" to output"<<endl;
minRailNo = n+2;//不可N+1,如果N+1的话,会和currentOut == minRailNo冲突,导致buffer[minRailNoBuffer].pop();失败
for (int index=0; index<k; index++)
{
//找出所有缓冲队列中最小的车厢号,上层判断能否出轨
if (!buffer[index].empty() && buffer[index].peek()<minRailNo)
{
minRailNo = buffer[index].peek();
minRailNoBuffer = index;
}
}
}
template<class T> bool CStackQueue<T>::HoldBufferReset_Stack(T data, int& minRailNo, int& minRailNoBuffer, CStack<T>
*buffer, int k, int n)
{
int bestbuffer = -1;//记录最适合发当前值的缓冲队列
int bestTop = n+1;//记录对应缓冲队列最上面值(即最小值)
for (int index=0; index<k; index++)
{
if (!buffer[index].empty())
{
//当队列不为空,判断放入值是否比最小值小,如果小则更新
//注意:此处的小是指大于放入值但是缓冲队列中最接近的
if (data < buffer[index].peek() && buffer[index].peek()<bestTop)
{
bestTop = buffer[index].peek();
bestbuffer = index;
}
}
else if (bestbuffer == -1)
{
//如果没有找到最适合的,就放入一个空缓冲队列中
bestbuffer = index;
}
}
if (bestbuffer == -1)
{
//如果数据没地方放,说明不可行
return false;
}
buffer[bestbuffer].push(data);
cout<<"Move rail "<<data<<" from input to holding track "<<bestbuffer+1<<endl;
//放入数据
if (data < minRailNo)
{
//如果放入的数据是所有缓冲队列中最小的,则更新minRailNo和minRailNo
minRailNo = data;
minRailNoBuffer = bestbuffer;
}
return true;
}
template<class T> void CStackQueue<T>::OutBufferReset_Queue(int& minRailNo, int& minRailNoBuffer, CQueue<T> *buffer, int k,
int n)
{
buffer[minRailNoBuffer].dequeue();
cout<<"Move rail "<<minRailNo<<" from holding track "<<minRailNoBuffer+1<<" to output"<<endl;
minRailNo = n+2;//不可N+1,如果N+1的话,会和currentOut == minRailNo冲突,导致buffer[minRailNoBuffer].pop();失败
for (int index=0; index<k; index++)
{
//找出所有缓冲队列中最小的车厢号,上层判断能否出轨
if (!buffer[index].empty() && buffer[index].backpeek()<minRailNo)
{
minRailNo = buffer[index].backpeek();
minRailNoBuffer = index;
}
}
}
template<class T> bool CStackQueue<T>::HoldBufferReset_Queue(T data, int& minRailNo, int& minRailNoBuffer, CQueue<T>
*buffer, int k, int n)
{
int bestbuffer = -1;//记录最适合发当前值的缓冲队列
int bestTop = -1;//记录对应缓冲队列最上面值(即最小值)
for (int index=0; index<k; index++)
{
if (!buffer[index].empty())
{
//当队列不为空,判断放入值是否比最小值小,如果小则更新
//注意:此处的小是指大于放入值但是缓冲队列中最接近的
T tmp = buffer[index].frontpeek();
if (data > buffer[index].frontpeek() && buffer[index].frontpeek()>bestTop)
{
bestTop = buffer[index].frontpeek();
bestbuffer = index;
}
}
else if (bestbuffer == -1)
{
//如果没有找到最适合的,就放入一个空缓冲队列中
bestbuffer = index;
}
}
if (bestbuffer == -1)
{
//如果数据没地方放,说明不可行
return false;
}
buffer[bestbuffer].enqueue(data);
cout<<"Move rail "<<data<<" from input to holding track "<<bestbuffer+1<<endl;
//放入数据
if (data < minRailNo)
{
//如果放入的数据是所有缓冲队列中最小的,则更新minRailNo和minRailNo
minRailNo = data;
minRailNoBuffer = bestbuffer;
}
return true;
}
template<class T> void CStackQueue<T>::BracketMatching_Stack(T *expr)
{
assert(expr!=NULL, "invalid parameter in BracketMatching, expr==NULL");
CStack<T> *stack = new CStack<T>(strlen(expr));
bool bmatching = true;
for (int index=0; index<strlen(expr) && bmatching; index++)
{
switch (expr[index])
{
case '(':
case '[':
case '{':
if (stack->full())
{
bmatching = false;
}
else
{
stack->push(expr[index]);
}
break;
case ')':
if (stack->empty())
{
bmatching = false;
}
else if (stack->pop() != '(')
{
bmatching = false;
}
break;
case ']':
if (stack->empty())
{
bmatching = false;
}
else if (stack->pop() != '[')
{
bmatching = false;
}
break;
case '}':
if (stack->empty())
{
bmatching = false;
}
else if (stack->pop() != '{')
{
bmatching = false;
}
break;
default:
break;
}
}
bmatching = stack->empty()?true:false;
if (bmatching)
{
cout<<"matching"<<endl;
}
else
{
cout<<"not matching"<<endl;
}
delete stack;
}
template<class T> void CStackQueue<T>::Hanio_Recursion(int n, T A, T B, T C)
{
if (n == 1)
{
cout<<"move "<<n<<" from "<<A<<" to "<<C<<endl;
}
else
{
//将n-1个从A移动B,用C作辅助
Hanio_Recursion(n-1, A, C, B);
//将第n个从A移到C
cout<<"move "<<n<<" from "<<A<<" to "<<C<<endl;
//将n-1个从B移动C,用A作辅助
Hanio_Recursion(n-1, B, A ,C);
}
}
template<class T> void CStackQueue<T>::Hanio_Unrecursion_Stack(int n)
{
CStack<T> *stack = new CStack<T>[3];
for (int index=0; index<3; index++)
{
stack[index].resize(n);
}
for (int index=0; index<n; index++)
{
//初始化,三个元柱,编号1,2,3......
stack[0].push(n-index);
}
long maxMoveNum = pow((double)2, n)-1; //总的移动此数
int curMoveNum = 0;
int curtry = 0;
int pillar = 0;
while (curMoveNum < maxMoveNum)
{
//按顺时针方向把圆盘1从现在的柱子移动到下一根柱子
curtry = stack[pillar%3].pop();
stack[(pillar+1)%3].push(curtry);
cout<<++curMoveNum<<"/t:move disk "<<curtry<< " from " <<pillar%3<<" to " <<(pillar+1)%3<< endl;
pillar++;
//把另外两根柱子上可以移动的圆盘移动到新的柱子上
if (curMoveNum < maxMoveNum)
{
int data1, data2;
//把非空柱子上的圆盘移动到空柱子上,当两根柱子都为空时,移动较小的圆盘
bool bempty1 = stack[(pillar+1)%3].empty();
if (!bempty1)
{
data1 = stack[(pillar+1)%3].peek();
}
bool bempty2 = stack[(pillar-1)%3].empty();
if (!bempty2)
{
data2 = stack[(pillar-1)%3].peek();
}
//if (!stack[(pillar+1)%3].peek(data1) ||
// stack[(pillar-1)%3].peek(data2) && data1 > data2)
if (bempty1 || !bempty2 && data1 > data2)
{
curtry = stack[(pillar-1)%3].pop();
stack[(pillar+1)%3].push(curtry);
cout<<++curMoveNum<<"/t:move disk "<<curtry<< " from " <<(pillar-1)%3<<" to " <<(pillar+1)%
3<< endl;
}
else
{
curtry = stack[(pillar+1)%3].pop();
stack[(pillar-1)%3].push(curtry);
cout<<++curMoveNum<<"/t:move disk "<<curtry<< " from " <<(pillar+1)%3<<" to " <<(pillar-1)%
3<< endl;
}
}
}
delete[] stack;
}
template<class T> void CStackQueue<T>::Rail_Rearrangement_Stack(T *data, int n, int k)
{
assert(data!=NULL, "invalid parameter in Rail_Rearrangement_Stack, data==NULL");
assert(n>0, "invalid parameter in Rail_Rearrangement_Stack, n=0");
assert(k<=n, "invalid parameter in Rail_Rearrangement_Stack, k>n");
//K个缓冲队列
CStack<T> *buffer = new CStack<T>[k];
for (int index=0; index<k; index++)
{
buffer[index].resize(n);
}
int currentOut = 1; //当前可以出轨的车厢号
int minRailNo = n+1; //缓冲队列中最小的车厢号
int minRailNoBuffer = 0;//缓冲队列中最小的车厢号所在的换冲队列
for (int railIndex=0; railIndex<n; railIndex++)
{
if (data[railIndex] == currentOut)
{
//找到最小的,可以直接出
cout<<"Move rail "<<currentOut<<" direct from holding track to output"<<endl;
currentOut++;
//出完后,到缓冲队列中寻找,哪些可以出轨,同时修改对应的minRailNo和minRailNoBuffer
while (currentOut == minRailNo)
{
OutBufferReset_Stack(minRailNo, minRailNoBuffer, buffer, k, n);
currentOut++;
}
}
else
{
//找到缓冲区中最合适的位置,放入值,同时更新minRailNo和minRailNoBuffer
if(!HoldBufferReset_Stack(data[railIndex],minRailNo,minRailNoBuffer,buffer,k,n))
return ;
}
}
cout<<"rail rearrangement success"<<endl;
delete[] buffer;
}
template<class T> void CStackQueue<T>::Rail_Rearrangement_Queue(T *data, int n, int k)
{
assert(data!=NULL, "invalid parameter in Rail_Rearrangement_Stack, data==NULL");
assert(n>0, "invalid parameter in Rail_Rearrangement_Stack, n=0");
assert(k<=n, "invalid parameter in Rail_Rearrangement_Stack, k>n");
CQueue<T> *buffer = new CQueue<T>[k];
for (int index=0; index<k; index++)
{
buffer[index].resize(n+1);
}
int currentOut = 1; //当前可以出轨的车厢号
int minRailNo = n+1; //缓冲队列中最小的车厢号
int minRailNoBuffer = 0;//缓冲队列中最小的车厢号所在的换冲队列
for (int railIndex=0; railIndex<n; railIndex++)
{
if (data[railIndex] == currentOut)
{
//找到最小的,可以直接出
cout<<"Move rail "<<currentOut<<" direct from holding track to output"<<endl;
currentOut++;
//出完后,到缓冲队列中寻找,哪些可以出轨,同时修改对应的minRailNo和minRailNoBuffer
while (currentOut == minRailNo)
{
OutBufferReset_Queue(minRailNo, minRailNoBuffer, buffer, k, n);
currentOut++;
}
}
else
{
//找到缓冲区中最合适的位置,放入值,同时更新minRailNo和minRailNoBuffer
if(!HoldBufferReset_Queue(data[railIndex],minRailNo,minRailNoBuffer,buffer,k,n))
return ;
}
}
cout<<"rail rearrangement success"<<endl;
delete[] buffer;
}
template<class T> void CStackQueue<T>::Switch_Box_Wiring_Stack(T *net, int n)
{
assert(net!=NULL, "invalid parameter in Switch_Box_Wiring, net==NULL");
assert(n>0, "invalid parameter in Switch_Box_Wiring, n=0");
CStack<T> *stack = new CStack<T>(n);
for (int index=0; index<n; index++)
{
if (stack->empty())
{
stack->push(net[index]);
}
else if (stack->peek() == net[index])
{
stack->pop();
}
else
{
stack->push(net[index]);
}
}
if (stack->empty())
{
cout<<"switch boxing wiring success"<<endl;
}
else
{
cout<<"switch boxing wiring fail"<<endl;
}
delete stack;
}
template<class T> void CStackQueue<T>::Offline_Equivalent_Class_Stack(T *data, int n, T *datapair, int npair)
{
assert(data!=NULL, "invalid parameter in Offline_Equivalent_Class, data==NULL");
assert(datapair!=NULL, "invalid parameter in Offline_Equivalent_Class, datapair==NULL");
assert(n>2, "invalid parameter in Offline_Equivalent_Class, n<2");
assert(npair>0, "invalid parameter in Offline_Equivalent_Class, npair<0");
int* pairIndex = new int[2*npair];
assert(pairIndex!=NULL, "allocate memory failed");
//将关系中的数据对在数据中的相对位置计算出来,便于后续使用
for (int index1=0; index1<2*npair; index1++)
{
for (int index2=0; index2<n; index2++)
{
if (datapair[index1] == data[index2])
{
pairIndex[index1] = index2;
break;
}
}
}
//记录哪些已经判断过了
bool* bqual = new bool[n];
assert(bqual!=NULL, "allocate memory failed");
memset(bqual,false,sizeof(bool)*n);
//记录属于当前类的数据
CStack<T> *stack = new CStack<T>(n);
assert(stack!=NULL, "allocate memory failed");
for (int index=0; index<n; index++)
{
//如果已经分类的就跳过去
if (bqual[index])
{
continue;
}
//开始一个新的分类
bqual[index] = true;
stack->push(index);
while (!stack->empty())
{
int curIndex = stack->pop();
cout<<data[curIndex]<<" ";
for (int index2=0; index2<npair; index2++)
{
//找到新分类的成员数据
int tmpIndex = 0;
if (pairIndex[2*index2] == curIndex)
{
tmpIndex = 2*index2+1;
}
else if (pairIndex[2*index2+1] == curIndex)
{
tmpIndex = 2*index2;
}
else
{
continue;
}
tmpIndex = pairIndex[tmpIndex];//计算数据中的对应位置
if (!bqual[tmpIndex])
{
//如果属于当前类的成员数据还没有被标记的话,则入栈
bqual[tmpIndex] = true;
stack->push(tmpIndex);
}
}
}
cout<<endl;
}
}
template<class T> void CStackQueue<T>::FindPath_MouseMaze_Stack(T *maze, int rows, int cols)
{
assert(maze!=NULL, "invalid parameter in FindPath_MouseMaze_Stack, maze==NULL");
//分配可以进行外围补1的迷宫数组
T **pmaze = new T*[rows+2];
for (int irow=0; irow<rows+2; irow++)
{
pmaze[irow] = new T[cols+2];
memset(pmaze[irow], 0, sizeof(T)*(cols+2));
}
//外围补1
for (int irow=0; irow<rows+2; irow++)
{
for (int icol=0; icol<cols+2; icol++)
{
if (irow == 0 || irow == rows+1 || icol == 0 || icol == cols+1)
{
pmaze[irow][icol] = 1;
}
}
}
for (int irow=0; irow<rows+2; irow++)
{
for (int icol=0; icol<cols+2; icol++)
{
cout<<pmaze[irow][icol]<<" ";
}
cout<<endl;
}
cout<<endl;
//将迷宫数据放入补1的内维中
for (int irow=0; irow<rows; irow++)
{
memcpy(pmaze[irow+1]+1, maze+(irow*cols), sizeof(T)*cols);
}
for (int irow=0; irow<rows+2; irow++)
{
for (int icol=0; icol<cols+2; icol++)
{
cout<<pmaze[irow][icol]<<" ";
}
cout<<endl;
}
cout<<endl;
//四个方向偏移 右 下 左 上
CPoint offset[4] = {CPoint(0,1), CPoint(1,0), CPoint(0,-1), CPoint(-1,0)};
CStack<CPoint> *smaze = new CStack<CPoint>(rows*cols);
assert(smaze!=NULL, "allocate memory failed");
//入口位置
CPoint curPos(1,1);
pmaze[curPos.x][curPos.y] = 1;
int curOption = 0;
while (curPos.x != rows || curPos.y != cols)
{
CPoint next = curPos;
while (curOption < 4)
{
//从四个方向找到一个可以走的方向
next.x = curPos.x + offset[curOption].x;
next.y = curPos.y + offset[curOption].y;
if (pmaze[next.x][next.y] == 0)
{
break;
}
curOption++;
}
if (curOption < 4)
{
//找到一个可以走的方向,前进一步,同时设置当前1
smaze->push(curPos);
curPos = next;
if (next.x == rows && next.y == cols)
{
//最后出口不用再走了,直接出来即可
smaze->push(curPos);
}
pmaze[curPos.x][curPos.y] = 1;
curOption = 0;
}
else
{
if (smaze->empty())
{
//无法回退一个位置(即堆栈为空),则表明不存在通往出口的路径
cout<<"no path"<<endl;
return;
}
CPoint prev = smaze->pop();
if (prev.y = curPos.y)
{
curOption = 3 + prev.x - curPos.x;
}
else
{
curOption = 2 + prev.x - curPos.x;
}
curPos = prev;
}
}
while (!smaze->empty())
{
//记录出口顺序
CPoint tmpPoint = smaze->pop();
pmaze[tmpPoint.x][tmpPoint.y] = 2;
}
//用*号显示路路径
for (int irow=0; irow<rows+2; irow++)
{
for (int icol=0; icol<cols+2; icol++)
{
if (pmaze[irow][icol] == 2)
{
cout<<"*"<<" ";
}
else
{
cout<<pmaze[irow][icol]<<" ";
}
}
cout<<endl;
}
cout<<endl;
}
template<class T> void CStackQueue<T>::FindPath_MouseMaze_Queue(T *maze, int rows, int cols)
{
assert(maze!=NULL, "invalid parameter in FindPath_MouseMaze_Stack, maze==NULL");
//分配可以进行外围补1的迷宫数组
T **pmaze = new T*[rows+2];
for (int irow=0; irow<rows+2; irow++)
{
pmaze[irow] = new T[cols+2];
memset(pmaze[irow], 0, sizeof(T)*(cols+2));
}
//外围补1
for (int irow=0; irow<rows+2; irow++)
{
for (int icol=0; icol<cols+2; icol++)
{
if (irow == 0 || irow == rows+1 || icol == 0 || icol == cols+1)
{
pmaze[irow][icol] = 1;
}
}
}
for (int irow=0; irow<rows+2; irow++)
{
for (int icol=0; icol<cols+2; icol++)
{
cout<<pmaze[irow][icol]<<" ";
}
cout<<endl;
}
cout<<endl;
//将迷宫数据放入补1的内维中
for (int irow=0; irow<rows; irow++)
{
memcpy(pmaze[irow+1]+1, maze+(irow*cols), sizeof(T)*cols);
}
for (int irow=0; irow<rows+2; irow++)
{
for (int icol=0; icol<cols+2; icol++)
{
cout<<pmaze[irow][icol]<<" ";
}
cout<<endl;
}
cout<<endl;
//四个方向偏移 右 下 左 上
CPoint offset[4] = {CPoint(0,1), CPoint(1,0), CPoint(0,-1), CPoint(-1,0)};
CQueue<CPoint> *smaze = new CQueue<CPoint>(rows*cols);
assert(smaze!=NULL, "allocate memory failed");
//入口位置
int curValue = 10;
CPoint curPos(1,1);
CPoint nextPos;
pmaze[curPos.x][curPos.y] = curValue;
smaze->enqueue(curPos);
int curOption = 0;
bool bFindPath = false;
while(!smaze->empty() && !bFindPath)
{
curOption = 0;
curPos = smaze->dequeue();
while (curOption < 4)
{
//从四个方向找到一个可以走的方向
nextPos.x = curPos.x + offset[curOption].x;
nextPos.y = curPos.y + offset[curOption].y;
if (pmaze[nextPos.x][nextPos.y] == 0)
{
pmaze[nextPos.x][nextPos.y] = pmaze[curPos.x][curPos.y] + 1;
if (nextPos.x == rows && nextPos.y == cols)
{
bFindPath = true;
}
smaze->enqueue(nextPos);
}
curOption++;
}
}
for (int irow=0; irow<rows+2; irow++)
{
for (int icol=0; icol<cols+2; icol++)
{
cout<<pmaze[irow][icol]<<" ";
if (pmaze[irow][icol] < 10)
{
cout<<" ";
}
}
cout<<endl;
}
cout<<endl;
nextPos.x = rows;
nextPos.y = cols;
bFindPath = false;
do
{
curPos = nextPos;
curOption = 0;
while (curOption < 4)
{
//从四个方向找到一个可以走的方向
nextPos.x = curPos.x + offset[curOption].x;
nextPos.y = curPos.y + offset[curOption].y;
if (pmaze[curPos.x][curPos.y] == pmaze[nextPos.x][nextPos.y] + 1)
{
pmaze[curPos.x][curPos.y] = 2;
if (pmaze[nextPos.x][nextPos.y] == 10)
{
pmaze[nextPos.x][nextPos.y] = 2;
bFindPath = true;
}
break;
}
curOption++;
}
} while (!bFindPath);
//用*号显示路路径
for (int irow=0; irow<rows+2; irow++)
{
for (int icol=0; icol<cols+2; icol++)
{
if (pmaze[irow][icol] == 2)
{
cout<<"*"<<" ";
}
else
{
cout<<pmaze[irow][icol]<<" ";
if (pmaze[irow][icol] < 10)
{
cout<<" ";
}
}
}
cout<<endl;
}
cout<<endl;
}
template<class T> void CStackQueue<T>::Identity_Map_Queue(T *map, int rows, int cols)
{
assert(map!=NULL, "invalid parameter in Identity_Map_Queue, map==NULL");
//分配可以进行外围补1的迷宫数组
T **pmap = new T*[rows+2];
for (int irow=0; irow<rows+2; irow++)
{
pmap[irow] = new T[cols+2];
memset(pmap[irow], 0, sizeof(T)*(cols+2));
}
//外围补1
for (int irow=0; irow<rows+2; irow++)
{
for (int icol=0; icol<cols+2; icol++)
{
if (irow == 0 || irow == rows+1 || icol == 0 || icol == cols+1)
{
pmap[irow][icol] = 0;
}
}
}
for (int irow=0; irow<rows+2; irow++)
{
for (int icol=0; icol<cols+2; icol++)
{
cout<<pmap[irow][icol]<<" ";
}
cout<<endl;
}
cout<<endl;
//将迷宫数据放入补1的内维中
for (int irow=0; irow<rows; irow++)
{
memcpy(pmap[irow+1]+1, map+(irow*cols), sizeof(T)*cols);
}
for (int irow=0; irow<rows+2; irow++)
{
for (int icol=0; icol<cols+2; icol++)
{
cout<<pmap[irow][icol]<<" ";
}
cout<<endl;
}
cout<<endl;
//四个方向偏移 右 下 左 上
CPoint offset[4] = {CPoint(0,1), CPoint(1,0), CPoint(0,-1), CPoint(-1,0)};
CQueue<CPoint> *smap = new CQueue<CPoint>(rows*cols);
assert(smap!=NULL, "allocate memory failed");
//入口位置
CPoint curPos;
CPoint nextPos;
int curValue = 2;
int curOption = 0;
for (int irow=1; irow<rows+1; irow++)
{
for (int icol=1; icol<cols+1; icol++)
{
if (pmap[irow][icol] != 1)
{
continue;
}
pmap[irow][icol] = curValue;
curPos.x = irow;
curPos.y = icol;
smap->enqueue(curPos);
while(!smap->empty())
{
curOption = 0;
curPos = smap->dequeue();
while (curOption < 4)
{
//从四个方向找到一个可以走的方向
nextPos.x = curPos.x + offset[curOption].x;
nextPos.y = curPos.y + offset[curOption].y;
if (pmap[nextPos.x][nextPos.y] == 1)
{
pmap[nextPos.x][nextPos.y] = curValue;
smap->enqueue(nextPos);
}
curOption++;
}
}
curValue++;
}
}
for (int irow=0; irow<rows+2; irow++)
{
for (int icol=0; icol<cols+2; icol++)
{
cout<<pmap[irow][icol]<<" ";
if (pmap[irow][icol] < 10)
{
cout<<" ";
}
}
cout<<endl;
}
cout<<endl;
//用*号显示路路径
for (int irow=0; irow<rows+2; irow++)
{
for (int icol=0; icol<cols+2; icol++)
{
if (pmap[irow][icol] != 0 && pmap[irow][icol] != 1)
{
cout<<"*"<<" ";
}
else
{
cout<<pmap[irow][icol]<<" ";
}
}
cout<<endl;
}
cout<<endl;
}
template<class T> void CStackQueue<T>::Factory_Simulation_Queue(CMachine* Machine, int machinenum, CTask* Task, int tasknum)
{
assert(Machine!=NULL, "invalid parameter in Factory_Simulation_Queue, Machine==NULL");
assert(machinenum>0, "invalid parameter in Factory_Simulation_Queue, machinenum<=0");
assert(Task!=NULL, "invalid parameter in Factory_Simulation_Queue, Task==NULL");
assert(tasknum>0, "invalid parameter in Factory_Simulation_Queue, tasknum<=0");
//输出基本信息
for (int index=0; index<tasknum; index++)
{
cout<<index+1<<"/t"<<Task[index].producenum<<"/t";
for (int index2=0; index2<Task[index].producenum; index2++)
{
cout<<"("<<Task[index].machineno[index2]<<","<<Task[index].worktime[index2]<<")";
}
cout<<endl;
}
//给队列分配空间时,计算最大的可能空间数
int totalTaskNum = 0;
for (int index=0; index<tasknum; index++)
{
totalTaskNum += Task[index].producenum;
}
//每个机器执行完当前任务的时间点
int *curTimePoint = new int[machinenum];
memset(curTimePoint,0,sizeof(int)*machinenum);
//当前时刻需要处理的任务,即队列中的最小时间点
int curMinTimePoint = INT_MAX;
CQueue<int>* machine = new CQueue<int>[machinenum];
for (int index=0; index<machinenum; index++)
{
machine[index].resize(totalTaskNum);
}
//初始任务入列
for (int index=0; index<tasknum; index++)
{
machine[Task[index].machineno[0]-1].enqueue(index+1);
}
//设置队列中当前任务的处理时间点
for (int index=0; index<machinenum; index++)
{
if (!machine[index].empty())
{
int taskIndex = machine[index].backpeek()-1;
int producetime = Task[taskIndex].worktime[Task[taskIndex].curproduce];
curTimePoint[index] = producetime;
curMinTimePoint = min(curMinTimePoint, producetime);
}
}
//当前处理中,哪些队列存在数据
bool *bWorkExist = new bool[machinenum];
memset(bWorkExist,0,sizeof(bool)*machinenum);
//判断整个流程是否结束,即所有机器队列数据都为空时,整个任务处理结束
bool bWorkEnd = false;
while (!bWorkEnd)
{
bWorkEnd = true;
for (int index=0; index<machinenum; index++)
{
cout<<index+1<<"/t"<<machine[index];
}
for (int index=0; index<machinenum; index++)
{
cout<<curTimePoint[index]<<" ";
}
cout<<endl<<"min:"<<curMinTimePoint<<endl;
for (int index=0; index<machinenum; index++)
{
bWorkExist[index] = machine[index].empty();
}
for (int index=0; index<machinenum; index++)
{
//如果队列中有任务
if (!bWorkExist[index])
{
bWorkEnd = false;
//该任务是否可以在当前时间点执行完
if (curTimePoint[index] != curMinTimePoint)
{
continue;
}
//如果执行完,则该任务的工序数加1
int curTaskIndex = machine[index].dequeue()-1;
Task[curTaskIndex].curproduce += 1;
if (Task[curTaskIndex].curproduce < Task[curTaskIndex].producenum)
{
//如果该任务没有处理完,将该任务的下一到工序放入对应的队列中
int nextProduce = Task[curTaskIndex].machineno[Task[curTaskIndex].curproduce]-1;
if (machine[nextProduce].empty())
{
//当队列为空时,则该任务的处理时间点由前提个任务的时间点加上当前工序的处理时间
curTimePoint[nextProduce] = curTimePoint[index]+
Task[curTaskIndex].worktime[Task[curTaskIndex].curproduce];
}
machine[nextProduce].enqueue(curTaskIndex+1);
}
if (!machine[index].empty())
{
//如果当前机器队列不为空,则取队列中下一个任务进行处理
int nextTaskIndex = machine[index].backpeek()-1;
int producetime = Task[nextTaskIndex].worktime[Task[nextTaskIndex].curproduce];
int switchtime = Machine[index].switchtime;
//更新时间点
curTimePoint[index] += producetime + switchtime;
}
}
}
curMinTimePoint = INT_MAX;
for (int index=0; index<machinenum; index++)
{
//重设下一个处理任务的时间点
if (!machine[index].empty())
{
curMinTimePoint = min(curTimePoint[index], curMinTimePoint);
}
}
}
for (int index=0; index<machinenum; index++)
{
cout<<curTimePoint[index] + Machine[index].switchtime<<" ";
}
cout<<endl;
}