求所有的出栈序列

来源:互联网 发布:linux安装gcc教程 编辑:程序博客网 时间:2024/04/29 05:21

 之前我们谈到验证一个出栈序列是否合法比较容易,简单模拟入栈出栈过程即可。那么如果需要求出所有合法的出栈序列该怎么办呢?
(1)我们之前谈到,合法的出栈序列条件:
对于每个已出栈数之后的且小于此数的数都必须按降序排列。例如1 2 5 3 4。对于5来说,后面的3,4都小于5,可是3,4却是升序的。则肯定不是合法的出栈序列。
由此可以想到我们可以求出所有的全排列,然后从中剔除掉非法序列。显然,当序列的长度增加时,多余的计算太多,效率太低。
(2)模拟入栈出栈过程,每次都有两种选择,要么入栈要么出栈。显然按照递归方式是可行的。但是又有一个问题,一般递归,很少牵扯到递归层次之间数据传送问题。而模拟这个过程时,栈的信息从上层传到下层,最后回到上层时,必然栈的状态早已被下层改了。解决办法就是,下层返回时,回复栈的原状态。这样递归就不会出错了。
代码如下:(如果大家还有更好的算法或写法欢迎大家交流讨论。自我感觉我写的这个不太好)

public class TestStackOut {private static Stack<String> stack = new Stack<String>();//栈private static Stack<String> list = new Stack<String>();//待装入栈的序列,也用栈来实现private static StringBuffer out = new StringBuffer();//输出串public static void recur(){//递归方法if(stack.empty() && list.empty()){//栈空,序列也空,则输出System.out.println(out);return;} else if(!stack.empty() && !list.empty()){//栈和序列都不空,要么入栈要么出栈//选择一:出栈String str = stack.pop();out.append(str);recur();out.deleteCharAt(out.length() - 1);//选择二:入栈。 注意:在入栈之前,应该把之前由于出栈而对out,stack,list造成的影响复原。stack.push(str);str = list.pop();stack.push(str);recur();str = stack.pop(); //入栈操作完后也得复原。list.push(str);} else if(!stack.empty() && list.empty()){String str = stack.pop();out.append(str);recur();//复原out.deleteCharAt(out.length() - 1);stack.push(str);} else if(stack.empty() && !list.empty()){String str = list.pop();stack.push(str);recur();//复原str = stack.pop();list.push(str);}}public static void main(String[] args) {list.push("5");list.push("4");list.push("3");list.push("2");list.push("1");recur();}}


 

原创粉丝点击