一、使用栈实现将中缀表达式转换为后缀表达式
算法:
1.创建一个栈 2.对于输入表达式中的每一个字符t: t是一个操作数→直接输出 t是右括号→当前栈顶出栈并输出该符号,直到一个左括号出栈(左括号不输出) t是操作符→读出当前栈顶,并输出栈顶符号,直到出现一个左括号或者优先级比t低的符号或者栈空 t入栈 3.出栈并输出该符号,直至栈空
二、使用栈计算后缀表达式的值
1.创建一个栈 2.对于后缀表达式中的每一个字符t: t是一个操作数→入栈 t是操作符→出栈两个元素,应用运算符t对其进行计算,并将结果入栈 3.栈顶的值即为计算结果
说明:只实现简单计算,个位数二元运算符的加减乘除,结果也为个位数,可以处理左括号右括号。
package stack; import java.util.LinkedList; import java.util.Scanner; /** * @author Administrator * @version 创建时间:2018年5月10日 上午8:32:53 * @ClassName 类名称 * @Description 类描述 */ class ArrayStack{ private int top; private char[] array; public ArrayStack(int capacity){ array = new char[capacity]; top = 0; } public boolean isEmpty(){ return(top==0); } public void push(char ch){ array[++top]=ch; } public char pop(){ return(array[top--]); } } public class Main { static String ss = new String();//后缀表达式 private static boolean isOperator(char oper){ if (oper=='+'||oper=='-'||oper=='/'||oper=='*' ||oper=='('||oper==')') { return true; } return false; } //计算操作符的优先级 private static int priority(char s){ switch (s) { case '+':return 1; case '-':return 1; case '*':return 2; case '/':return 2; case '(':return 3; case ')':return 3; default :return 0; } } //中缀表达式转为后缀表达式 private static void transferToPostfix(char[] a){ ArrayStack op = new ArrayStack(20); //创建栈,栈的深度为10 for(int i = 0; i<a.length;i++){ char t = a[i];//输入字符串中的每个字符t if(!isOperator(t)){//t是一个操作数 System.out.print(t);//输出t ss=ss+t;//char类型转String!!!! String.valueOf(c) }else if(t==')'){//t是一个右括号 char temp=op.pop(); while(temp!='('){ System.out.print(temp);//出栈并输出该符号,直到一个左括号出栈 ss=ss+temp; temp=op.pop();//左括号出栈,左括号不输出 } }else{//t是一个运算符或左括号 char temp=op.pop();//读出栈顶元素 op.push(temp); //出栈并输出该符号,直到出现一个比t的优先级小的符号,或者出现一个左括号,或者栈空 while(priority(temp)>=priority(t)&&temp!='('&&!op.isEmpty()){ System.out.print(temp); ss=ss+temp; temp = op.pop(); } op.push(t);//t入栈 } } while(!op.isEmpty()){ char temp=op.pop(); System.out.print(temp); ss=ss+temp; } } private static int cal(int num1,int num2,char operator){ switch (operator){ case '+':return num1+num2; case '-':return num1-num2; case '*':return num1*num2; case '/':return num1/num2; default :return 0; } } //根据后缀表达式计算结果 private static void calculate(String str){ ArrayStack ca = new ArrayStack(20); //创建栈,栈的深度为10 char a[] = str.toCharArray(); for (int i = 0; i<a.length;i++) { char s = a[i];//输入字符串中的每个字符t if (isOperator(s)){ if (!ca.isEmpty()){ int num1=Integer.valueOf(ca.pop())-Integer.valueOf('0'); int num2=Integer.valueOf(ca.pop())-Integer.valueOf('0'); if (s=='/'&&num1==0){ System.out.println("除数不能为0"); return; } int newNum=cal(num2,num1,s); ca.push((char)(newNum+'0')); } } else { //数字则压入栈中 ca.push(s); } } if (!ca.isEmpty()){ System.out.println("result: "+ca.pop()); } } public static void main(String[] args) { Scanner sc = new Scanner(System.in); char[] a = sc.next().toCharArray(); transferToPostfix(a); calculate(ss); } }
三、设计一个栈的getMin、pop、push方法
思路:使用两个栈,一个用来存储当前栈中的元素,一个用来存每一步的最小值
import java.util.Stack; public class MyStack1 { private Stack<Integer> stackData; private Stack<Integer> stackMin; public MyStack1(){ this.stackData = new Stack<Integer>(); this.stackMin = new Stack<Integer>(); } public void push(int newNum){ if (this.stackData.isEmpty()){ this.stackMin.push(newNum); }else if( newNum <= this.getmin()){ this.stackMin.push(newNum); } this.stackData.push(newNum); } public int pop(){ if(this.stackData.isEmpty()){ throw new RuntimeException ("Your stack is empty"); } int value = this.stackData.pop(); if(value == this.getmin()){ this.stackMin.pop(); } return value; } public int getmin(){ if (this.stackMin.isEmpty()){ throw new RuntimeException("Your stack is empty"); } return this.stackMin.peek(); //peek()查看栈顶的对象而不移除它 } public static void main(String[] args) { MyStack1 stack1 = new MyStack1(); stack1.push(3); System.out.println(stack1.getmin()); stack1.push(4); System.out.println(stack1.getmin()); stack1.push(1); System.out.println(stack1.getmin()); System.out.println(stack1.pop()); System.out.println(stack1.getmin()); } }