栈相关
两个栈实现队列:
public class Solution { Stack<Integer> stack1 = new Stack<Integer>(); Stack<Integer> stack2 = new Stack<Integer>(); public void push(int node) { stack1.push(node); } public int pop() { int a; if(stack2.isEmpty()){ while(!stack1.isEmpty()){ a=stack1.top(); stack2.push(a); stack1.pop(); } } a=stack2.top(); stack2.pop(); return a; } }
判断栈的压入弹出序列
public boolean IsPopOrder(int [] pushA,int [] popA) { if(pushA.length==0) return false; Stack<Integer> stack=new Stack<Integer>(); for(int i=0,j=0;i<pushA.length;i++){ stack.push(pushA[i]); while(j<popA.length&&stack.peek()==popA[j]){ stack.pop(); j++; } } return stack.isEmpty(); }
一个带加减乘除括号的表达式计算值
public class Main { public static void main(String[] args) { // TODO Auto-generated method stub Main m=new Main(); String str="(56-20)/(4+2) ";//这里需要一个空格方便处理最后一位 char[] res=m.trans(str.toCharArray()); System.out.print(m.compute(res)); } //把一个算数表达式转换为后缀表达式 public char[] trans(char[] exp) { int i=0,j=0; char c=exp[i]; i++; char[] postexp=new char[100]; Stack<Character> stack=new Stack<>(); while(i<exp.length) { switch (c) { case '(': stack.push('('); break; case ')': while(stack.peek()!='(') { postexp[j]=stack.pop(); j++; } stack.pop();//把(也弹出去 break; case '+': case '-': while(!stack.isEmpty()&&stack.peek()!='(') { //要把其他符号弹出来(可能乘除,也可能和它同一个等级的) postexp[j]=stack.pop(); j++; } stack.push(c); break; case '*': case '/': while(!stack.isEmpty()&&stack.peek()!='('&&(stack.peek()=='*'||stack.peek()=='/')) { //同级的先弹出去 postexp[j]=stack.pop(); j++; } stack.push(c); break; case ' ':break; default: while(c>='0'&&c<='9') { postexp[j]=c;j++; c=exp[i];i++; } i--;//到不是数字的时候需要往前移动一位,因为最后的时候都会往后移动一位的 postexp[j]='#';j++; break; } c=exp[i];i++; } while(!stack.isEmpty()) { postexp[j]=stack.pop(); j++; } return postexp; } //根据后缀表达式计算值 public double compute(char[] postexp) { Stack<Double> stack=new Stack<>(); int i=0; char c=postexp[i]; i++; //这个地方边界还有点问题,后面可以用链表 while(i<13) { switch (c) { case '+': double after=stack.pop(); double pre=stack.pop()+after; stack.push(pre); break; case '-': double afterb=stack.pop(); double preb=stack.pop()-afterb; stack.push(preb); break; case '*': double afterc=stack.pop(); double prec=stack.pop()*afterc; stack.push(prec); break; case '/'://这里可能有除0操作需要判断 double afterd=stack.pop(); double pred=stack.pop()/afterd; stack.push(pred); break; default: double d=0; while(c>='0'&&c<='9') { d=10*d+c-'0'; c=postexp[i]; i++; } //这里不用回退是因为有一个#刚好跳过去 stack.push(d); break; } c=postexp[i];i++; } return stack.peek(); } }
用栈来排序:
一个栈作为输入栈,一个作为输出栈,拿出输入栈栈顶元素,去和输出栈比较,找到第一个比他小的,上面的元素全部压入输入栈
//in是输入栈 public Stack<Integer> sort(Stack<Integer> in){ Stack<Integer> out=new Stack<>(); if(in.isEmpty()) return out; int temp = in.peek(); in.pop(); if(in.isEmpty()) { out.push(temp); return out; } while(!in.isEmpty()||out.peek()>temp) { if(out.isEmpty()||out.peek()<=temp) { out.push(temp); temp=in.peek(); in.pop(); } else { in.push(out.peek()); out.pop(); } } out.push(temp); return out; }
找出来数组中每个元素后边第一个比它大的值A=[1,5,3,6,4,8,9,10] 输出[5, 6, 6, 8, 8, 9, 10, -1]
用栈来实现是需要O(n)的时间复杂度
public int[] findMax(int[] a) { Stack<Integer> stack=new Stack<>(); int i=0; while(i<a.length) { if(!stack.isEmpty()&&a[i]>a[stack.peek()]) { a[stack.pop()]=a[i]; } else { stack.push(i++); } } while(!stack.isEmpty()) { a[stack.pop()]=-1; } return a; }
对于只有乘法和加法的算术表达式计算结果:
public static int normalCal(char[] a) { if(a.length==1) return a[0]-48; Stack<Integer> stack = new Stack<>();//数字栈 Stack<Character> ctack = new Stack<>();//符号栈 int i=0; while(i<a.length) { int temp=0; boolean flag=false; while(i<a.length&&a[i]>='0'&&a[i]<='9') { temp=temp*10+(a[i]-48); flag=true; i++; } if(flag) {//这一轮数字结束了,需要取出符号来计算了,当然只有乘号才弹出来 stack.push(temp); if(!ctack.isEmpty()&&ctack.peek()=='*') { int k=stack.peek(); ctack.pop(); stack.pop(); k*=stack.peek(); stack.pop(); stack.push(k); } } if(i<a.length&&(a[i]=='+'||a[i]=='*')) { ctack.push(a[i]); i++; } } int size=stack.size(); int res=0; for(int j=1;j<=size;j++) { res+=stack.peek(); stack.pop(); } return res; }
括号嵌套,没遇到一个括号就反转字符串,当括号不匹配,直接返回-1
(ab(cd(ef(gh)))) 返回cdghfeba
(ab(cd))(ef(gh)) 返回cdbaghfe
对于空括号的边界还是没有考虑
(ab(cd(ef(gh))))()()返回就会不对
public class Main { public static void main(String[] args) { Scanner sc=new Scanner(System.in); String str=sc.nextLine(); Stack<Character> stack=new Stack<>(); Stack<String> Sstack=new Stack<>(); for(int i=0;i<str.length();i++) { StringBuilder sb=new StringBuilder();//放在外面防止出现()空括号的情况 if(str.charAt(i)=='(') { stack.push('('); continue; } if(str.charAt(i)>='a'&&str.charAt(i)<='z') { while(str.charAt(i)>='a'&&str.charAt(i)<='z') { sb.append(str.charAt(i)); i++; } i--;//上面那个会跳过去 Sstack.push(sb.toString());//防止空括号 } if(str.charAt(i)==')') { if(!stack.isEmpty()) { stack.pop();//左括号出栈 String aaa=Sstack.peek(); StringBuilder temp=new StringBuilder(Sstack.peek());//字符串出栈 Sstack.pop(); String help=""; if(!Sstack.isEmpty()) { help=Sstack.peek()+temp.reverse().toString();//再取栈顶的连接起来 Sstack.pop(); } else help=temp.reverse().toString();//再取栈顶的连接起来 Sstack.push(help);//新组成的再进栈 } else { System.out.println("括号不匹配不满足情况"); return; } } } if(!stack.isEmpty()) { System.out.println("括号不匹配不满足情况"); return; } String res=""; while(!Sstack.isEmpty()) { res=Sstack.pop()+res; } System.out.println(res); } }
本文来自博客园,作者:LeeJuly,转载请注明原文链接:https://www.cnblogs.com/peterleee/p/11205357.html

浙公网安备 33010602011771号