描述:
火车编号为:1~9,且不重复。
如:编号分别为“1”、“2”、“3”、“4”、“5”的5个火车顺序进站,那么进站序列为“12345”,全部进站后再顺序出站,则出站序列为“54321”,如果先进1,2,然后2出站,然后1出站,然后再3进站、出站,4进站、出站,5进站、出站,那么出站序列就为21345.
详细描述:
int JudgeTrainSequence (int maxNum, char *pOutSeq);
输入参数:
int maxNum:进站的火车最大编号
char* pOutSeq:使用字符串表示火车出站序列
输出参数(指针指向的内存区域保证有效):
无。
返回值:
Int: 根据输入的进站序列判断,如果输入的出站序列是可能的,返回1,否则返回0;
一、分析(假如编号为1,2,3,4,5,6,7):
1,若数n出栈,则在n出栈只有<n的数一定已经入栈(可能有部分数在n出栈之前就已经出栈);
2,本着后入先出的原则,如果第一个出栈的是4,则1、2、3的出栈先后顺序只能为3、2、1(中间允许有其它数);
3,如果第二个出栈的数>4,例如为6,即现出栈为4、6,则现在栈中一定有1、2、3、5,这四个数的出栈先后顺序只能为5、3、2、1;
4,如果第二个出栈的数<4,那只能为3,栈中现有1、2;
5,依此类推;
二、模拟入栈出栈过程(假如出栈序列为4673251):
1,1~7依此入队,记录当前队尾元素为q_tail=1;
2,出栈序列中当前元素为4,则队列中q_tail<=ele<=4依此出列并入栈,4出栈,记录队尾元素q_tail=5;
3,出栈序列当前元素指向6,判断6!=栈顶元素&&6>=q_tail,则q_tail<=ele<=6依此出列并入栈,6出栈,记录队尾元素q_tail=7;
4,出栈序列当前元素指向7,判断7!=栈顶元素&&7>=q_tail,则q_tail<=ele<=7依此出列并入栈,7出栈,队列为空,记录队尾元素q_tail=null;
5,出栈序列当前元素指向3,判断3!=栈顶元素&&q_tail=null,则无法让3出栈,return false;
三、注意问题:
1,形参pOutSeq不能为NULL,且只能为1-9的纯数字组成;
2,pOutSeq里的数字不能重复;
3,pOutSeq最少得有一个数字;
四、算法实现:
#include <iostream>
#include <stack>
#include <queue>
#include <string>
using namespace::std;
inline bool IsValidNum(char *str)
{
if(str == NULL || strlen(str)==0 || strlen(str)>9)
return false;
else
{
char *p = str;
while(*p !='\0')
{
if(*p<'0' || *p>'9')
return false;
else p++;
}
return true;
}
}
int JudgeTrainSequence (int maxNum, char *pOutSeq)
{
if( !IsValidNum(pOutSeq) )
return false;
else if(maxNum != strlen(pOutSeq))
return false;
//创建一个队列和栈
queue<unsigned int> que;
stack<unsigned int>stk;
//序号依次入队
for(int i=0; i<maxNum; i++)
que.push(i+1);
char *p_cur_ele = pOutSeq;
//第一个元素的出栈过程
for(int i=0; i<*p_cur_ele-'0'; i++)
{
stk.push(que.front());
que.pop();
}
stk.pop();
unsigned int q_tail;
if(que.empty())
q_tail = 0;
else
q_tail = que.front();
while(*++p_cur_ele != '\0')
{
if(!stk.empty() && !que.empty())
{
if(*p_cur_ele-'0' != stk.top() && *p_cur_ele-'0'>=q_tail)
{
for(int i=0; i<*p_cur_ele-'0'-q_tail+1; i++)
{
stk.push(que.front());
que.pop();
}
if(que.empty())
q_tail = 0;
else q_tail = que.front();
stk.pop();
}
else if(*p_cur_ele-'0'==stk.top())
stk.pop();
else
return false;
}
else if(!stk.empty() && que.empty())
{
if(*p_cur_ele-'0'==stk.top())
stk.pop();
else
return false;
}
else if(stk.empty() &&!que.empty())
{
for(int i=0; i<*p_cur_ele-'0'-q_tail+1; i++)
{
stk.push(que.front());
que.pop();
}
stk.pop();
if(que.empty())
q_tail = 0;
else q_tail = que.front();
}
else
return false;
}
return true;
}
int main()
{
char str[100] = {'\0'};
int maxNum;
cin>>maxNum;
cin>>str;
int ret = JudgeTrainSequence(maxNum,str);
cout<<"ret is : "<<ret<<endl;
return 0;
}