一、使用栈实现将中缀表达式转换为后缀表达式
算法:
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());
}
}