栈-出栈序列正确性分析

问题很简单:在栈的性质下,1~n的数字按顺序入栈,给出它们的出栈序列,判定该序列是否合理。

 

相比于之前遇到过的“求解所有可行出栈序列”,本问题的复杂度着实降低了不少。不过要把这个过程正确地通过code模拟出来,在逻辑的处理上也需要注意不少细节。

下面先来讲讲处理的方法:

    程序输入:n以及给定的出栈序列,出栈序列不妨设为q[n+1],其中q[1]~q[n]顺序保存正确性未知的出栈序列。

    由于入栈是按顺序入栈,可以不用额外的数组保存,仅需要一个递增的标志A表示即可。同时,出栈序列也需要一个指针B来保存当前序列首部q[B]。

           同时需要一个栈stk来保存压栈的数字

    循环执行以下几步:

           (1)比较当前序列首q[B]与A是否相等,相等则表示对当前的入栈数字A来说,它入栈后立即出栈,A自增1,出栈序列指针后移,即B自增1

           (2)若不相等,那么转而判断栈顶元素是否和当前出栈序列首部相等,若相等,则栈顶元素出栈,出栈序列指针继续后移。

           (3)若(1)(2)都不满足,则判断A是否已经大于n了,大于则不满足出栈条件,并跳出循环,小于等于则将当前数字A压栈,并自增1,转而跳(1)

C++实现代码如下

 1 #include<iostream>
 2 #include<stack>
 3 using namespace std;
 4 int n;          //输入个数
 5 int f[100];     //保存出队序列 
 6 stack<int> stk;
 7 int main(){
 8     cin>>n;
 9     for(int i=1;i<=n;++i)
10         cin>>f[i];
11     int B=1,A=1;   //出队序列指针
12     bool flag=1;
13     while(B<=n){
14         if(f[B]==A){  //直接比较未入栈序列首部与当前序列首部 
15             A++;
16             B++;
17         }
18         else if(!stk.empty() && stk.top()==f[B]){       //比较栈顶和首部
19             stk.pop();
20             B++;
21         } 
22         else if(A<=n){                            //若A还有剩余的元素 
23             stk.push(A++);        
24         }
25         else{
26             flag=0;break;
27         } 
28     } 
29     if(flag) cout<<"yes";
30     else     cout<<"no";
31     return 0;
32 } 

 

posted @ 2016-05-22 23:30  Holy炭  阅读(1125)  评论(0编辑  收藏  举报