题目:输入两个整数序列。其中一个序列表示栈的入栈顺序,判断另一个序列有没有可能是对应的出栈顺序。
思路:用一个辅助栈,将入栈序列按照某种顺序入栈,看是否可以产生出栈序列即可。
1)如果当前栈为空,且入栈序列不空,则入栈序列的下一个元素入栈;
2)如果当前辅助栈的栈顶元素不等于出栈序列的首元素,那么入栈序列一直入栈,直到入栈序列为空。
3)如果当前辅助栈的栈顶元素等于出栈序列的首元素,那么栈顶元素弹出,出栈序列第一个元素移走;
4) 如果入栈序列为空,出栈序列第一个元素仍然不等于栈顶元素,则表示2个序列是不匹配的。
举例:
栈的特点是后进先出,假设入栈的顺序是 1 2 3 4 5,出栈的顺序是:4 5 3 2 1,这样操作的顺序是:push 1, push 2,push 3,push 4,pop 4, push 5 , pop 5,pop 3, pop 2, pop 1。假设出栈的顺序是4 5 3 1 2,这种顺序是错误的,因为1比2先压入栈,所以2的出栈顺序应该是1之前,显然出栈顺序是错误的。下面使用程序进行验证
代码如下:
#include <iostream>
#include <stack>
#include <cstring>
using namespace std;
//给定入栈序列判断出栈序列是否合法,stkIn表示入栈序列,stkOut表示出栈序列
bool JudgeIsLegal(char *stkIn, char *stkOut)
{
stack<char> midStk;//判断过程中借助的中间辅助栈
if(strlen(stkIn) != strlen(stkOut)){//若入栈与出栈的元素个数不同的话,直接返回false
return false;
}
midStk.push(*stkIn++);//入栈序列的第一个元入栈
while(*stkOut != '\0'){//如果出栈序列没有匹配完
if(midStk.empty() && *stkIn!='\0')//若辅助栈已空说明目前出栈和入栈序列是匹配的,如果入栈序列不为空,继续入栈
midStk.push(*stkIn++);
//如果辅助栈的栈顶元素和出栈序列第一个元素不一致,那么就将入栈序列继续入栈
while(*stkOut != midStk.top() && *stkIn != '\0'){
midStk.push(*stkIn++);
}
//如果栈顶元素和出栈序列第一个元素一致,那么就将栈顶元素出栈,并且匹配出栈序列下一个元素
if(*stkOut == midStk.top()){
stkOut++;
midStk.pop();
continue;
}
//如果入栈序列已为空,但是栈顶元素和出栈序列第一个元素扔不一致,则说明这2个串不是匹配的。
if(*stkIn == '\0' && midStk.top() != *stkOut){
return false;
}
}
return true;
}
int main()
{
char *str ="12345";
char *str2 = "45312";
if (JudgeIsLegal(str,str2))
{
cout<<"该出栈序列合法!"<<endl;
}else{
cout<<"该出栈序列非法!"<<endl;
}
return 0;
}