出栈序列的合法性
来源:互联网 发布:linux hello world 编辑:程序博客网 时间:2024/05/16 11:38
问题描述:对于一个进栈序列其出栈序列存在多种合法的可能情况。例如:入栈序列为1,2,3,4,5时,而对于出栈序列5,4,3,2,1、1,3,2,5,4、3,5,4,2,1等等这些都是一个合法的出栈序列,但是对于3,5,2,4,1、5,3,4,2,1等这种出栈序列则是非法的序列,因为其违背了栈的特性(先进后出或者后进先出)。
★对于1,2,3,4,5这样的进栈序列,我们最常想到的出栈序列为5,4,3,2,1。这是因为将其一次性逐个入栈,然后逐个弹出得到的出栈序列。然而在这里我们并未规定所有元素入栈后才相继弹出,所以这里的序列就很多很多了。
比如:以上述一个合法的出栈序列1,3,2,5,4为例:再比如:以上述一个非法的出栈序列3,5,2,4,1为例:
①栈为空,元素1入栈,然后弹出。①栈为空,元素1,2,3入栈,元素3弹出(此时栈内保留压入元素1,2)。
②元素2,3入栈,元素3,2分别弹出。 ②元素4,5入栈,此时栈内为1,2,4,5,然后元素5出栈(栈内剩余元素1,2,4)。
③元素4,5入栈,元素5,4分别弹出,得到该合法序列1,3,2,5,4。③此时要让元素2出栈,但是此时滞留在栈内的栈顶元素为4,所以该序列非法。
①在此我们先来看看数组的实现:
#include<iostream>using namespace std;int main(){int i, j, k;int temp;//存放第一个可能比s[i]小的数int num = 0;int flag1,flag2;//两个标志位,一个标记存在比s[i]小的数,另一个为标记序列的合法性cin >> num;int *s = new int[num]; //动态开辟数组,注意结束时的回收(delete[] s) for (i = 0; i < num; i++)cin >> s[i];for (i = 0; i < num; i++)//寻找是否存在比s[i]小的数{flag1 = 0;flag2 = 0;for (j = i + 1; j < num; j++)if (s[j]<s[i])//如果存在,则将其放入到temp变量中,并将flag1标志位置为1{temp = s[j]; flag1 = 1;break;}if (flag1 == 1)//在标志位为1的前提下,继续寻找是否仍存在比s[i]小的数,并且比temp小的数,存在则不断更新temp的值for (k = j + 1; k < num; k++)if (s[k]<s[i]) if (s[k]<temp) temp = s[k];else //否则将序列合法性的标志位置为1{flag2 = 1;break;}if (flag2 == 1)//非法的序列{cout << "illegal sequence!" << endl;exit(0); }}cout << "legal sequence!" << endl;//合法的序列 delete[] s;return 0;}
★注:分析上述的代码我们不难看出,对于入栈序列1,2,3,4,5来说,其判断一个出栈序列的合法性的标准为出栈序列中,元素i之后比其小的元素必须是降序排列的。
②数组有其局限性,比如整型数组存放整型值,字符数组存放字符串,所以我们可以利用指针来做,对于其类型的问题,我们可以借助模板来实现。
#include<iostream> #include<stack> #include<cstring>#include<cassert> using namespace std;bool judge(const char *sour, const char *dest)//不比更改两个序列的内容,所以可加const修饰限定符{ assert(sour);<span style="white-space:pre"></span>//断言可防止NULL指针的传入(避免传入指针引起程序崩溃的问题) assert(dest);stack<char> ss;<span style="white-space:pre"></span>//借助库函数创建一个栈if (strlen(sour) != strlen(dest)) <span style="white-space:pre"></span>//如果两个序列不一样长,自然是非法的序列return false;ss.push(*sour++); <span style="white-space:pre"></span>//将首元素压栈while (*dest != '\0') {if (ss.empty() && *sour != '\0') <span style="white-space:pre"></span>//如果栈为空且入栈序列未结束,则不断压入元素ss.push(*sour++);while (*dest != ss.top() && *sour != '\0') {ss.push(*sour++); <span style="white-space:pre"></span>//如果出栈元素和栈顶元素不匹配则继续压入元素}if (*dest == ss.top()) <span style="white-space:pre"></span>//如果两者相等,将该元素弹出,且指针指向出栈序列的下一位置上{dest++;ss.pop();continue;}if (*sour == '\0'&& ss.top() != *dest) //如果一直不相等,知道入栈序列结束仍为匹配上,说明出栈序列非法{return false;}}return true;<span style="white-space:pre"></span>//否则序列合法}int main(){char *str1 = "abcbd";char *str2 = "abdbc";int ret = judge(str1, str2);cout << ret << endl;return 0;}
★注:对于上述代码,只是实现了字符串的类型比较。要接受任意类型的参数,比如浮点型,自定义类型,结构体类型等就可以实现C++中的模板类,以实现代码的复用。
例如:
template<class T>bool judge(const T*sour,const T*dest,size_t size,size_t size) //注意此时要传入序列的大小,并且创建栈时的类型也须换成T
结语:代码执行流程的顺序图在此就不画了,本人画图工具用的不6,不美观,读者可自行画图帮助理解。
- 出栈序列的合法性
- 【数据结构】 出栈序列的合法性【面试】
- 出栈的合法性
- 出栈的合法性检测
- 栈 入栈序列与出栈序列 合法性 的一个有趣问题
- 【数据结构】检查元素出栈的合法性
- 【数据结构】判断出栈顺序的合法性
- 出栈顺序合法性
- 出栈合法性
- 判断出栈顺序合法性
- 判断元素出栈合法性
- 元素的出栈、入栈顺序的合法性。
- 栈--元素出栈、入栈顺序的合法性问题
- 元素出栈、入栈顺序的合法性
- 判断元素入栈/出栈的合法性
- 元素入栈、出栈的合法性检测
- 元素出栈、入栈顺序的合法性
- 判断元素出栈,入栈顺序的合法性
- 数据仓库的星形和雪花模型
- eclipse或者myeclipse中竖直选择代码
- openjdk编译和调试
- 《STL源码剖析》---stl_hashtable.h阅读笔记
- android数据库SQLite(2)
- 出栈序列的合法性
- 打印蛇形数组——两种结构
- 第三次上机作业
- CF 346 B vector<pair> s[100]
- 整理Ruby相关的各种概念(rvm, gem, bundle, rake, rails等)
- 随便取十个数1
- 【推荐】可查找下载和上传动漫外挂字幕网站
- MaterialDesign之NavigationView和DrawerLayout实现侧滑菜单栏
- LeetCode *** 58. Length of Last Word