数据结构——栈—出栈顺序的可能情况
来源:互联网 发布:淘宝转盘抽奖怎么做 编辑:程序博客网 时间:2024/06/14 09:25
这是一个大一在计算机导论上就提出的问题,在给定待入栈元素顺序(可以中途出栈)的情况下,有多少中情况?当时看了一篇有关的博客,其中用了动态规划的思想解决了这个问题:
设有f(n)种情况;考虑第一个元素1出栈的位置,若在第一个出栈,则只需考虑剩下n-1个元素的出栈情况,即f(n-1),若第二个出栈,前面有一个元素已经出栈(只能是2),后面有n-2个元素待入栈,则有f(1)*f(n-2)情况;若第三个出栈,前面有2个元素已经出栈(只能是2、3),后面有n-3个元素待入栈,则有f(2)*f(n-3)情况;
所以得到递归方程(n) = f(0)*f(n-1) + f(1)*f(n-2) + ... + f(n-1)*f(0)
即
这个式子也可以用组合数计算出来,结果是
但是要输出所有情况不能用这种方法输出
下面给出代码实现:
package popAll; import java.util.Stack; import java.util.Scanner; /* 要讨论所有元素可能的出入栈顺序,思想与计算可能的出入栈顺序情况不同,后者是用动态规划的思想, 将规模为n的情况转化为n个规模为n-1的情况从而实现递归,但是前者要输出每一种具体情况,用动态 规划就不太适合。当第一个元素入栈后,可以出栈或者进栈,所以这有两个选择,不停的重复这两个选 择,直到输入序列和栈中序列都为空就完成了一种情况。所以只要先选一种选择,当完成这种选择后面 的操作后,恢复之前的状态,进行下一次选择,就可得到全都情况,这是一种回溯的思想。 */ public class popAll { int amount = 0;//统计可能情况数目 int getAmount() {//返回数目 return amount; } void outPut(Stack<Integer> outSeq)// 输出可能序列 { amount++; Integer temp; Stack<Integer> alternative = new Stack<Integer>(); //这个过程有两个作用,一举两得 //由于输出出栈顺序需要把输出序列的栈全部输出一遍,这个过程完成后输出胡序列会变为空,所以要用另一栈来接收输出序列中的元素 //而且由于出栈的情况是储存在栈中,要从头输出出栈情况必须先将栈中元素全部反过来再从栈尾输出; //但是储存出栈序列用数组存起来 会不会更方便? while (!outSeq.empty()) alternative.push(outSeq.pop()); while (!alternative.empty()) { temp = alternative.pop(); System.out.print(temp); outSeq.push(temp); } System.out.println(); } void iniStack(Stack<Integer> stack, Integer n) {//初始化入栈序列,分别用从1到n的元素来标记元素及元素入栈顺序 for (int i = n; i > 0; i--) stack.push(i); } void allPopSeq(Stack<Integer> inSeq, Stack<Integer> inStack, Stack<Integer> outSeq) { if (inSeq.empty() && inStack.empty()) outPut(outSeq); else { if (!inSeq.empty())// 选择入栈 { Integer temp = inSeq.pop();// 保存并入栈 inStack.push(temp); allPopSeq(inSeq, inStack, outSeq);// 进行下一选择 inStack.pop(); inSeq.push(temp);// 恢复到之前状态 } if (!inStack.empty()) { Integer temp = inStack.pop();// 保存并出栈 outSeq.push(temp); allPopSeq(inSeq, inStack, outSeq);// 进行下一选择 outSeq.pop(); inStack.push(temp);// 恢复到之前状态 } } } public static void main(String[] args) { Integer n; Stack<Integer> inSeq = new Stack<Integer>();// inSeq准备入栈序列 Stack<Integer> inStack = new Stack<Integer>();// inStack栈中序列 Stack<Integer> outSeq = new Stack<Integer>();// outSeq输出序列 popAll seq = new popAll(); Scanner scan = new Scanner(System.in); System.out.println("请输入入栈序列中数据个数"); n = scan.nextInt(); seq.iniStack(inSeq, n); System.out.println("可能的序列为:"); seq.allPopSeq(inSeq, inStack, outSeq); System.out.println("共" + seq.getAmount() + "种情况"); } }
那么如何判断给定的一个序列是否为可能的出栈序列呢?
下面给出代码实现:
import java.util.Stack;import java.util.Scanner;/*通过模拟入栈的情况来判断序列是否为可能的出栈序列;从给出的序列第一个开始,依次压栈比较当前栈顶元素与出栈序列中的元素,如果相同,查看下一个出栈序列中的元素并出栈,直到序列检查完,则是可能的情况;如果不同,继续压栈,直到所有元素都压进栈还不符合,则是不可能的情况 */public class JudgeStack {void iniArray(Stack<Integer> stack,int n)//初始化用于判断比较的栈{for(int i=n;i>0;i--)stack.push(i);}boolean judge(int n,int array[]) {//开始判断int i=0;Stack<Integer> inPutSeq=new Stack<Integer>();//待输入序列Stack<Integer> inStack=new Stack<Integer>();//栈中iniArray(inPutSeq,n);while(i<n)//最后一位判断完后自动跳出循环{if(inStack.empty())//栈中没元素时要先从待输入序列中压一个进去inStack.push(inPutSeq.pop());if(array[i]!=inStack.peek()&&!inPutSeq.empty())//当前情况与期望不符且待输入序列不为空时继续压栈{inStack.push(inPutSeq.pop());continue;//此时一定要跳出这次循环,不然当待输入序列为空时无法进行最后一次比较}else if(array[i]==inStack.peek())//当前为与期望相符,{inStack.pop();i++;continue;}if(inPutSeq.empty())//当前情况与期望不符且待输入序列为空时跳出,此时一定不是可能的出栈顺序break;}if(i==n)return true;else return false; }public static void main(String[] args){JudgeStack judge=new JudgeStack();boolean isStack;int n;String str;Scanner scan=new Scanner(System.in);System.out.println("请输入待检查数列(默认从1到n为待入栈序列):");str=scan.nextLine();char chars[]=str.toCharArray();int array[]=new int[str.length()];for(int i=0;i<str.length();i++)//将输入字符串转化为整型数组array[i]=(int)(chars[i]-48);n=str.length();isStack=judge.judge(n,array);System.out.println(isStack);}}
阅读全文
0 0
- 数据结构——栈—出栈顺序的可能情况
- 给定入栈顺序,输出所有可能出栈情况及所有情况的总数
- 序列所有可能的出栈顺序
- 数据结构经典问题——出栈顺序
- 【数据结构】判断出栈顺序的合法性
- DFS 遍历数组所有可能存在的出栈顺序
- N个数顺序进栈,出栈的情况
- 给定入栈顺序,输出所有可能的出栈情况,并判断给定的序列是否为正确的输出序列
- 指定栈的进栈顺序,输出所有可能的出栈顺序
- 根据入栈顺序得出所有可能的出栈顺序(c++)
- 根据入栈顺序输出所有可能的出栈顺序 (Java)
- 给定入栈顺序,求所有可能的出栈顺序
- 给定一个入栈顺序和一个出栈顺序,判断出栈顺序是否可能
- 数据结构顺序栈的入栈与出栈
- 数据结构—栈的顺序的实现
- NOJ1098Rails——出栈顺序
- 数据结构——顺序栈的学习
- 数据结构——栈的顺序存储
- 西安软件开发
- 使用谷歌浏览器出现黑色块或者点点
- 点击文字复制到剪切板
- 使用ICON动态修改exe文件图标
- C++/CLI 创建WPF程序
- 数据结构——栈—出栈顺序的可能情况
- 面试题
- 喜迎国庆,欢度中秋,联科教育送大礼!
- bzoj 2152:聪聪可可(点分治)
- 免费馅饼 dp
- bzoj3206 [Apio2013]道路费用(kruskal+并查集+状压枚举+dfs)
- TCP的三次握手
- 心脏出血漏洞修复记录
- centos 更改源