判断一个入栈出栈的顺序释放符合条件:
输入两个序列表:一个是压栈的顺序列表 arr 第二个是输出的结果列表 result
判断输出的结果列表符不符合压栈出栈条件:
#include <iostream>
#include <stack>
using namespace std;
stack<int> st_f;
int justy(int *arr,int *result){
int i,j=0;
for(i=0;i<5;i++){//遍历每一个结果result
for(int temp=j;temp<5;temp++){//在入栈顺序的数组arr中找到当期与result数组对应的数
if(result[i]==arr[temp])//如果找到了,那就把result匹配数和在他之前的全部入栈
{
for(int temp2=j;temp2<=temp;temp2++)
st_f.push(arr[temp2]);
j=temp+1;//把入栈顺序数组进行标记
break;
}
}
if(!st_f.empty()&&st_f.top()==result[i])//如果辅助的栈没为空,并且它有与result【i】相等
{ //就弹出,表示符合条件
st_f.pop();
}
else if(!st_f.empty()&&st_f.top()!=result[i]) {//表示不符合条件
//cout<<"push's can't success";
return 0;
}
}
if(!st_f.empty()) return 0;//如果到了最后辅助栈不为空,也是不符合条件的。
return 1;
}
int main(){
int arr[5]={1,2,3,4,5};
int result[5]={4,5,3,2,1};
if(justy(arr,result))
cout<<"stack's reult is ture";
else
cout<<"stack's is false";
return 0;
}
最找到牛人分析编号为 1 到 n 的 n 个元素,顺序的进入一个栈,则可能的出栈序列有多少种?就转载了:如下
近日在复习数据结构,看到栈的时候,发现1个元素进栈,有1种出栈顺序;2个元素进栈,有2种出栈顺序;3个元素进栈,有5种出栈顺序,那么一个很自然地问题就是n个元素进栈,共有多少种出栈顺序?
说来惭愧,以前学数据结构的时候竟然没有考虑过这个问题。最近在看动态规划,所以“子问题”这3个字一直在我脑中徘徊,于是解决这个问题的时候我也是用类似“子问题”的方法,说白了就是递推公式。
我们把n个元素的出栈个数的记为f(n), 那么对于1,2,3, 我们很容易得出:
f(1) = 1 //即 1
f(2) = 2 //即 12、21
f(3) = 5 //即 123、132、213、321、231
然后我们来考虑f(4), 我们给4个元素编号为a,b,c,d, 那么考虑:元素a只可能出现在1号位置,2号位置,3号位置和4号位置(很容易理解,一共就4个位置,比如abcd,元素a就在1号位置)。
分析:
1) 如果元素a在1号位置,那么只可能a进栈,马上出栈,此时还剩元素b、c、d等待操作,就是子问题f(3);
2) 如果元素a在2号位置,那么一定有一个元素比a先出栈,即有f(1)种可能顺序(只能是b),还剩c、d,即f(2), 根据乘法原理,一共的顺序个数为f(1) * f(2);
3) 如果元素a在3号位置,那么一定有两个元素比1先出栈,即有f(2)种可能顺序(只能是b、c),还剩d,即f(1),
根据乘法原理,一共的顺序个数为f(2) * f(1);
4) 如果元素a在4号位置,那么一定是a先进栈,最后出栈,那么元素b、c、d的出栈顺序即是此小问题的解,即 f(3);
结合所有情况,即f(4) = f(3) + f(2) * f(1) + f(1) * f(2) + f(3);
为了规整化,我们定义f(0) = 1;于是f(4)可以重新写为:
f(4) = f(0)*f(3) + f(1)*f(2) + f(2) * f(1) + f(3)*f(0)
然后我们推广到n,推广思路和n=4时完全一样,于是我们可以得到:
f(n) = f(0)*f(n-1) + f(1)*f(n-2) + ... + f(n-1)*f(0)
即
//输出全部的可能性
//思路:这里有开始的栈input ,压入的栈 s,准备输出的栈 output 那么就可以通过对这三个栈进行处理就能得到结果;
1.
stacksqe(&input,&s,&output){
if input is empty
把s中的栈全放入output栈中,然后输出
else //有两种情况 的操作:1.看看s栈中有没有栈,如果有栈进行出栈放到output中,然后调用stacksqe继续递归 2.进行入栈 让input中的元素继续入栈 s中 ,然后调用stacksque继续递归 这得注意的是: 这两种可能时要求stacksqe中的input,s,output独立,不相互影响,所以要有副本来进行控制;(这样是用递归的时候要注意的事情,多个可能性的情况下,要注意各自的状态的正确性)
}
#include <stdio.h>
#include <malloc.h>
typedef struct{
int *stk;
int top;
int size;
}stack;
void initstack(stack *s, int n) {
s-> stk = (int*)malloc((s-> size=n) * sizeof(int));
s-> top = 0;
}
void copystack(stack *ss, stack *s) {
int i;
if(ss-> stk) free(ss-> stk);
ss-> stk = (int*)malloc((ss-> size=s-> size) * sizeof(int));
ss-> top = s-> top;
for(i=s->top-1;i>=0;i--)
ss->stk[i]=s->stk[i];
}
void outputstack(stack* s) {
int i;
for(i=0;i<s-> top;i++) printf("%2d",s-> stk[i]);
printf("\n");
}
int stackempty(stack* s) {
return !s-> top;
}
void push(stack* s, int x) {
s-> stk[s-> top++] = x;
}
int pop(stack* s) {
return s-> stk[--s-> top];
}
void stackseq(stack *input, stack *s, stack *output) {
/*初始状态:栈input中存放要输入的元素,s, output为空
结束状态:input 和 s 均为空 */
stack ii, ss, oo;
ii.stk=ss.stk=oo.stk=NULL;//必须要初始化,因为如果没有初始化那么就会使得数没定义,会出错
if(stackempty(input)) { /*如果数据已经全部输入完毕*/
while(!stackempty(s)){
push(output,pop(s));
}
outputstack(output);
}
else { /*还有元素要输入*/
if(!stackempty(s)) { /*我们需要保存现有状态*/
copystack(&ii, input);
copystack(&ss, s);
copystack(&oo, output);
push(&oo, pop(&ss));
stackseq(&ii, &ss, &oo);
}
push(s,pop(input)); /*再输入一个元素*/
stackseq(input, s, output);
}
}
void main()
{
int i,n;
stack input,s,output;
initstack(&input,20);
initstack(&s,20);
initstack(&output,20);
printf("Input n:\n");
scanf("%d",&n);
for(i=n;i> 0;i--)
push(&input,i);
stackseq(&input,&s,&output);
}