中缀表达式转后缀表达式步骤:
(1)初始两个栈:运算符栈s1 存储中间结果的栈s2
(2)从左往右扫描中缀表达式
(3)遇数 直接压入栈s2
(4)遇运算符:
a、如果s1为空或栈顶运算符号为 “ ( ”,直接将其压入栈s1
b、如果运算符的优先级比s1栈顶元素的优先级高,将运算符压入栈s1
c、如果运算符的优先级小于等于栈顶元素运算符,将栈顶元素弹出并压入栈s2 再次转到(4)的操作
(5)遇到括号:
a、左括号直接入栈s1
b、右括号 依次弹出s1栈顶的运算符并将其压入栈s2,直到遇到左扩号为止,将左括号弹出,此时完成对这一对扩号的丢弃
(6)重复2-5操作 直至遍历完中缀表达式
(7)将s1中剩余的运算符依次弹出并压入s2
(8)依次弹出s2中的元素并输出,结果的逆序即为中缀表达式的后缀表达式的形式
逆波兰计算器
- 1、逆波兰表达式》》从左往右依次扫描 —遇到数字存入栈中,遇到运算符,依次弹出栈顶和次栈顶元素计算结果,将结果存入栈中 —遍历结束,栈中只有一个元素即为最终的结果
//将字符串转换成中缀表达式
public static List<String> toMPoland(String str){
char[] c=str.toCharArray(); //字符串转成字符数组,遍历字符数组转成 list
String s; //对多位数的拼接
ArrayList<String> list=new ArrayList<String>();
for(int i=0;i<c.length;i++) {
if(c[i]<48||c[i]>57) { //如果是一个运算符 (注:每一个字符都有对应的ASCII值)
list.add(""+c[i]); //直接添加到list中 (注;字符转字符串的方法)
}else { //若果是一个数 不能直接存入list 因为要考虑它后面是否还是数字
s="";
while((i<c.length)&&((c[i]>=48)&&(c[i]<=57))){ //判断i的下一位是否是数字 如果是添加在之前的数字后面
s+=c[i]; //多位数的拼接
i++;
}
i--; //直到条件不满足 即c[i]不为数 由于在进入整个大的for循环之前,i会自动加1 所以此处需将i-1
list.add(s); //将得到的多位数加入到list中
}
}
return list;
}
//运算符的优先级的比较
public static int priority(String str) {
if(str.equals("*")||str.equals("/")) {
return 2;
}else {
return 1;
}
}
//将中缀表达式转成后缀表达式
public static List<String> toRevPoland(List<String> list){
//存放运算符号的栈
Stack<String> s1=new Stack<String>();
//分析的时候 是一个数栈 但由于在此处数只需要存入而不需要弹出 所以可以用List代替数栈
List<String> s2=new ArrayList<>();
for(int i=0;i<list.size();i++) {
String element=list.get(i);
if(element.matches("\\d+")) { //如果是一个数 直接存入数组中 !!!利用了正则表达式
s2.add(element);
}else //如果是一个运算符
//遇到左括号
if(element.equals("(")) { //左扩号直接入栈
s1.push("(");
}else if(element.equals(")")) { //遇到右扩号
while(!s1.peek().equals("(")) {
s2.add(s1.pop());
}
s1.pop(); //将对应的左扩号丢弃
}else if(s1.isEmpty()||s1.peek().equals("(")) { //如果s1栈为空 或栈顶元素为左括号“(”
s1.push(element); //直接将运算符入栈
}else {
while((s1.size()!=0)&&priority(s1.peek())>=priority(element)) { //如果s1不为空且栈顶运算符的优先级大于等于遍历的运算符的优先级
s2.add(s1.pop()); //弹出栈顶元素 将其压入s2
}
s1.push(element);
}
}
while(s1.size()!=0) {
s2.add(s1.pop());
}
return s2; //由于s2是ArrayList 所以结果就是逆波兰表达式
}
//逆波兰表达式计算器
public static void calculate(List<String> list) {
int num1=0;
int num2=0;
int res=0;
Stack<String> stack=new Stack<>();
for(String e:list) { //如果是数字 入栈
if(e.matches("\\d+")) { //匹配的是多位数
stack.push(e);
}else { //如果是符号 从栈中弹出两位数 进行对应的计算 然后再将其存入栈中
if(e.equals("+")) {
num1=Integer.parseInt(stack.pop());
num2=Integer.parseInt(stack.pop());
res=num1+num2;
} else if (e.equals("-")){
num1=Integer.parseInt(stack.pop());
num2=Integer.parseInt(stack.pop());
res=num2-num1;
}else if(e.equals("*")) {
num1=Integer.parseInt(stack.pop());
num2=Integer.parseInt(stack.pop());
res=num2*num1;
}else if(e.equals("/")) {
num1=Integer.parseInt(stack.pop());
num2=Integer.parseInt(stack.pop());
res=num2/num1;
}else { //如果不是数也不是运算符 将抛出异常
throw new RuntimeException();
}
stack.push(""+res);
}
}
System.out.println("计算的结果是:"+Integer.parseInt(stack.pop())); //计算到最后 栈中只有一个元素 即为最终的运算结果
}