铁路栈的问题

描述:

火车编号为: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;
}


 

 

   

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值