栈的实际应用—判断一个序列是否为栈的有效输出序列

对于数据结构学科的初学者,栈的构建是很重要的知识,判断一个栈是否为有效输出序列是其中重要的题目。笔者整理了三种C++代码,其核心编程思想大致相同,希望能对初学者有一定帮助。

**【问题描述】**给出一个堆栈的输入序列,试判断一个序列是否能够由这个堆栈输出。如果能,则为有效输出,返回总的出栈次数,如果不能,则为无效输出,返回0。序列的输入及输出都是从左往右。

1、输入输出序列皆为正整数,可能有重复的数字

2、如果一个数字在输入序列中没有出现,但在输出序列中出现,则为无效输出。

3、如果一个数字在输入序列中出现,但在输出序列中没有出现,只要输出可以通过对输入数字进行出栈操作获取,仍然为有效输出。

**【输入形式】**第一行包含两个数字:输入序列的长度与输出序列的长度;第二行为输入序列的数字;第三行为输出序列的数字。输入数据以空格隔开。

**【输出形式】**如果是一个有效的出栈序列,则返回总的出栈次数, 否则返回0

【样例输入1】
5 5
1 2 3 4 5
4 5 3 2 1
【样例输出】5
【样例说明】可以按以下顺序执行:
push(1), push(2), push(3), push(4), pop() -> 4, push(5), pop() -> 5, pop() -> 3, pop() -> 2, pop() -> 1
通过5次pop操作可以得到输出序列,因此返回5

【样例输入2】
5 5
1 2 3 4 5
4 3 5 1 2
【样例输出】0
【样例说明】1不能在2之前输出,因此返回0

**算法思想:**这个题目中涉及出栈、入栈等操作,很自然想到需要申请一个空间作为栈,进行相应的模拟操作。对于我们所要输出的序列,可以从头至尾一个个来操作,拿到最开始要输出的数字时,可以与输入序列相比较,如果恰好正确则直接输出,如果不相等则入栈,继续从前往后扫描输入序列。
举例来讲,如上述样例输入1,第一个要输出的数字是4,那么将这个数字依次与输入序列相比较,其中1、2、3与4并不相等,依次进栈,这时遇到了输入序列的4,这个4就可以输出了。下一个要输出的是5,先比较栈顶的数字3,与5并不相等,继续扫描输入序列找到5.依次类推,直到完成所有数据的输出。

算法1
这个算法利用了一个数组stack作为栈,也是笔者在拿到这个题目时做出的算法。其中代码行数比较少,思路也相对比较容易。

#include <iostream>using namespace std;bool pop(int sta[],int in[],int &curin,int &cur,int out);int main()
{int numin,numout,current=1,total=0,currentin=0;    //需要设出两个表示下标的变量,分别代表栈的下标和输入序列读取到的下标cin>>numin>>numout;int *p,*q,*stack;p=new int[numin];q=new int[numout];stack=new int[numin];for(int i=0;i<numin;++i) cin>>p[i];  //读入输入序列for(int i=0;i<numout;++i) cin>>q[i]; //读入输出序列stack[0]=p[0];     //输入序列第一个数入栈for(int i=0;i<numout;++i)     //从第一个输出序列的数字依次开始寻找if(pop(stack,p,currentin,current,q[i])==false)   //如果没有寻找到某一个输出数字,直接输出结果0{total=0;break;}else {total+=1;currentin-=1;}   //找到输出数字,那么出栈后栈的下标数字减1cout<<total;return 0;
}bool pop(int sta[],int in[],int &curin,int &cur,int out)   //判断并出栈的函数
{for(;in[cur-1]!='\0';++cur) {                           //依次遍历栈顶和输入序列剩余的数字if(sta[curin]==out) {sta[curin]=in[cur];return true;}   //找到则更替栈顶数字,返回trueelse{curin+=1;sta[curin]=in[cur];}}return false;                                           //没找到,返回false
}

具体的思路和代码如上。

算法2
编写一个类来代替传统的STL。代码来自笔者室友。

#include<iostream>
#include<cstdio>
using namespace std;template<class elemType>
class ownstack
{private:elemType *elem;int top_p;int max_size;void doublespace();public:ownstack(int initSize=100);   //栈的构造~ownstack();                  //析构bool empty();                 //判断栈空elemType top();               //取栈顶元素elemType pop();               //出栈void push(const elemType &x); //进栈
};template<class elemType>
ownstack<elemType>::ownstack(int initSize)
{elem=new elemType[initSize];max_size=initSize;top_p=-1;
};template<class elemType>
bool ownstack<elemType>::empty()
{return top_p==-1;
}template<class elemType>
ownstack<elemType>::~ownstack()
{delete []elem;
}template<class elemType>
elemType ownstack<elemType>::top()
{return elem[top_p];
}template<class elemType>
void ownstack<elemType>::push(const elemType &x)
{if(top_p==max_size-1) doublespace();elem[++top_p]=x;
}template<class elemType>
elemType ownstack<elemType>::pop()
{return elem[top_p--];
}template<class elemType>
void ownstack<elemType>::doublespace()
{elemType *tmp=elem;elem=new elemType[2*max_size];for(int i=0;i<max_size;++i)elem[i]=tmp[i];max_size*=2;delete []tmp;
}int judge(const int*pPush,const int *pPop,int length,int len)
{                                         //依次为输入、输出序列、输入序列剩余长度、输出序列剩余长度bool flag=false;if(pPush&&pPop&&length>0){const int *pNextPush=pPush;const int *pNextPop=pPop;ownstack<int>data;while(pNextPop-pPop<len)  //当pop中还有数字{//当data为空,或者栈顶元素不是pop序列当前的值//则向data中pushwhile(data.empty()||data.top()!=*pNextPop){//如果push序列为空,则跳出!if(!pNextPush){break;}data.push(*pNextPush);if(pNextPush-pPush<length-1)  pNextPush++;  //如果输入序列还有数字,可以继续入栈else break;           //pNextPush==NULL}if(data.top()!=*pNextPop) break;data.pop();pNextPop++;}if(pNextPop-pPop==len) flag=true;}  //进栈数字的数目等于要输出数列的数字个数,则判断为正确if(flag) return len;             //判断正确,返回输出数列的长度else return 0;    //其余情况判断为错误,输出为0
}int main()
{int m=0,n=0,i;scanf("%d%d",&m,&n);     //这里使用了scanf函数,效率高。cin.get();int push[m];int pop[n];for(i=0;i<m;i++)scanf("%d",&push[i]);cin.get();for(i=0;i<n;i++)scanf("%d",&pop[i]);cout<<judge(push,pop,m,n);return 0;
}

算法3
这种算法利用了STL。在进行栈的构建时,STL可以说是现成的工具。看到在本网站已经有了很好的STL构建,将相应的博主echo_xiao9的原文链接列出,希望读者也能关注一下这种较为方便实用的算法。
算法链接

总结来说,这道题目的大致思路是一样的,具体的算法实现和代码书写,笔者罗列了三种形式(其三为转载链接)。希望能对C++语言以及数据结构的初学者有所帮助。

判断一个序列是否为栈的有效输出序列相关推荐

  1. 《剑指offer》:[22]如何判断一个序列是否为栈的弹出序列

    题目:输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序. 假设压入栈的所有数字均不相等.例如序列1,2,3,4,5是某栈的压栈序列,序列4,5,3,2,1是该压栈序列 ...

  2. 判断一个数列是不是搜索二叉树后续遍历输出的结果

    剑平面阿里被问到这个,刚开始画了下看有什么性质,乱蒙了几个都被推翻了,初始感觉就是要O(n)的,因为印象中BST的构树都可以O(nlogn)搞定.然后剑平说最后一个数肯定是根节点,一下反应过来了,就是 ...

  3. 判断一个序列是否是栈的输出序列(原理和源码(C语言))

    [问题描述] 给出一个堆栈的输入序列,试判断一个序列是否能够由这个堆栈输出.如果能,返回总的出栈次数,如果不能,返回0.序列的输入及输出都是从左往右.(输入输出序列皆为整数且没有重复的数字,如果一个数 ...

  4. 栈的压入序列和弹出序列是否匹配

    给两个数组pushed和poped,其中pushed为栈的压入序列,popped为栈的弹出序列,判断第一个序列是否是第一个序列的弹出序列.假设压入栈的所有数字均不相等. 分析:辅助栈判断. class ...

  5. 给定入栈序列,判断一个串是否为出栈序列

    剑指offer22:给定入栈序列,判断一个串是否为出栈序列 public static boolean isOutStackSequence(int[] Spush, int[] Spop) {if ...

  6. 判断一个序列是否可由给定序列通过栈操作获得

    Java代码: public class LegalSequence {public static void main(String[] args) {// System.out.println(le ...

  7. Java判断一个序列是否可由给定序列通过栈操作获得(ABCDEF)

    Java栈操作中的代码题目你是否已经掌握了呢?接下来上题目叭~~~ 判断一个序列是否可由给定序列通过栈操作获得(ABCDEF) 这是基础题噢 学不会就打你pp呜呜呜~ 还是那句话,原创禁止转载侵权必究 ...

  8. 栈的push、pop序列-判断序列是否是栈的pop顺序

    程序员面试题精选100题(24)-栈的push.pop序列[数据结构] 题目:输入两个整数序列.其中一个序列表示栈的 push 顺序,判断另一个序列有没有可能是对应的 pop 顺序.为了简单起见,我们 ...

  9. 回文是指正读反读均相同的字符序列,如“abba”和“abdba”均是回文,但“good”不是回文。编写一个程序,使用栈判定给定的字符序列是否为回文。

    内容: 回文是指正读反读均相同的字符序列,如"abba"和"abdba"均是回文,但"good"不是回文.编写一个程序,使用栈判定给定的字符 ...

最新文章

  1. 视频播放器——开源免费三大代表
  2. linux 命令终端显示-bash-4.2#解决方法
  3. 【转】前端进阶之路:如何高质量完成产品需求开发
  4. 【写作技巧】中文摘要及关键词的撰写
  5. PHP开发入门 | 简单的PHP新闻管理系统案例
  6. eclipse下载哪个版本开发java_官网上有很多版本的eclipse,下载哪个版本比较合适?...
  7. 苹果手机以旧换新价格表_苹果支持安卓手机以旧换新;索尼公司将更名;百度网盘推出“防误删”文件恢复服务...
  8. 【GEE笔记】最大类间方差法(otsu、大津法)算法实现——计算阈值、图像二值化分割
  9. C#程序设计--控制台程序输出上下三角形和菱形
  10. 一文说清:可逆与不可逆加密算法,对称与非对称加密算法-据说BCrypt比MD5要好?
  11. Xilinx FPGA MIPI 接口简单说明
  12. Spring bean解析 - refresh
  13. 电气工程类期刊最新数据+2019年电气工程领域的中文期刊(EI期刊+中文核期刊)
  14. 2018个人面试记录
  15. php 8bit 10bit 解码,求助:我想把10bit的MKV压制成8bitMP4
  16. 未来人工智能发展面临的问题
  17. oppo java模拟器_java动物声音模拟器
  18. iOS 解决scoryboard上tableview、collection view顶部有空白问题
  19. SpringBoot 优雅的读取yml(yml规范篇)
  20. 整站优化提升排名工具_百度快速排名教程【常见问题】

热门文章

  1. byte[]转String出现乱码(EFBFBD或3F)
  2. @Vaild注解使用详解
  3. 1e9个兵临城下 - 容斥原理
  4. Linux系统编程:IPC信号量
  5. 什么样男人必出轨 震惊!出轨男子名字中居然都有这字
  6. PS仿制图章工具、油桶工具、渐变
  7. Pytorch中的dataset类——创建适应任意模型的数据集接口
  8. SAP PS 第9节 合并采购申请、组合WBS之详解
  9. Android模仿新浪微博(自定义ListView下拉刷新)
  10. [转]天龙八部的BillingServer