栈的使用-中缀表达式转后缀表达式

不多说,直接上代码 注释写的还算清楚,就不再啰嗦了

package wq;

import java.util.Stack;

/**
 * @author wq
 * 计算类,中缀表达式转后缀表达式
 */
public class Calculator {
	Stack<Integer> operatorStack=new Stack<Integer>();//符号栈
	String expression ;//中缀表达式
	public Calculator(String expression ) {
		expression=expression.replaceAll(" ", "");//去除空格
		this.expression=expression;
	}
	public static void main(String[] args) {
		Calculator calculator=new Calculator("9 +(3-1)*3+ 10/2");
		System.out.println(calculator.getSuffixExpression());
	}
	
	/**
	 * 获取后缀表达式
	 * @return
	 */
	String getSuffixExpression(){
		char[] tmpExp=expression.toCharArray();
		StringBuffer newExp=new StringBuffer();
		int index=0;//从左往右依次读取字符,记录读到的位置
		while(index<tmpExp.length){
				if(nextIsOperator(tmpExp,index)){
					int op=getOp(tmpExp,index);//读取下一个操作符
					//获取栈顶符号   为空则默认使用'(' 代替,目前'('优先级最低
					int popOp=operatorStack.isEmpty()?'(':operatorStack.peek();
					index++;
					switch(op){
					case '+':
					case '-':
						if(op1Higher(op, popOp)){//如果遇到的操作符优先级高,直接入栈
							operatorStack.push(op);
						}
						
						else {
							int tmpOp=0;
							//依次弹出栈内 低于当前操作符的其他操作符
							while(!operatorStack.isEmpty()&&!op1Higher(op,(tmpOp=operatorStack.pop()))){
								newExp.append((char)tmpOp);  
								System.out.print((char)tmpOp);
							}
							operatorStack.push(op);//入栈
						}
						
						break;
					case '*':
					case '/':
						if(op1Higher(op, popOp)){
							operatorStack.push(op);
						}
						break;
					case '(':
						operatorStack.push(op);
						break;
					case ')':
						int tmpOp;
						//依次弹出栈内 操作符 直到遇到'(' 为止
						while(!operatorStack.isEmpty()&&(tmpOp=operatorStack.pop())!='('){
							newExp.append((char)tmpOp);
							System.out.print((char)tmpOp);
						}
						break;
					}
				}else {//数字直接输出
					int num= getNum(tmpExp,index);
					index=index+String.valueOf(num).length();
					newExp.append(num);
					System.out.print(num);
				}
		}
		while (!operatorStack.isEmpty()) {//所有符号出栈
			int op=operatorStack.pop();
			newExp.append((char)op);
			System.out.print((char)op);
		}
		System.out.println();
		return newExp.toString();
	}

	/**
	 * 判断操作符op1 是否具有更高的优先级(可能有漏洞
	 * @param op1
	 * @param op2
	 * @return
	 */
	private boolean op1Higher(int op1,int op2){
		if(op2=='(' ||(op1=='*'||op1=='/')){//运算符op1具有更高的优先级,表示可以直接入栈
			return true;
		}else if(op2!='(' && (op1=='+' || op1=='-')){
			return false;
		}
		return false;
	}
	
	/**
	 * 获取下一个数字
	 * @param tmpExp
	 * @param offect
	 * @return
	 */
	private int getNum(char[] tmpExp,int offect) {
		int num=0;
		for (int i = offect; i < tmpExp.length; i++) {
			if(Character.isDigit(tmpExp[i])){
				num=num*10+tmpExp[i]-'0';//字符转数字
			}else{
				break;
			}
		}
		return num;
	}

	/**
	 * 获取下一个操作符
	 * @param tmpExp
	 * @param offect
	 * @return
	 */
	private char getOp(char[] tmpExp,int offect) {
		
		return tmpExp[offect];
	}

	/**
	 * 判断下一个字符是否为操作符
	 * @param tmpExp
	 * @param offect
	 * @return
	 */
	private boolean nextIsOperator(char[] tmpExp,int offect) {
		char op=tmpExp[offect];
		return (op=='+'||op=='-'||op=='*'||op=='/'||op=='('||op==')');
	}
	
}


转换逻辑可以参考百度百科 后缀表达式



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
中缀表达式转后缀表达式过程可以通过来实现。具体步骤如下: 1. 初始化两个一个用于存储运算符的OPTR,一个用于存储转换后的后缀表达式OPND。 2. 从左到右扫描中缀表达式,如果遇到操作数,则直接压入OPND中;如果遇到运算符,则与OPTR顶元素进行比较,如果该运算符优先级高于OPTR顶元素,则将该运算符压入OPTR中;否则,将OPTR顶元素弹出并压入OPND中,直到该运算符优先级高于OPTR顶元素或OPTR为空,然后将该运算符压入OPTR中。 3. 如果遇到左括号,则直接压入OPTR中;如果遇到右括号,则将OPTR顶元素弹出并压入OPND中,直到遇到左括号,然后将左括号弹出。 4. 当扫描完整个中缀表达式后,将OPTR中剩余的运算符依次弹出并压入OPND中。 5. 最后,将OPND中的元素依次弹出,即可得到转换后的后缀表达式。 下面是一个示例代码,供参考: ``` #include <iostream> #include <stack> #include <string> using namespace std; int priority(char op) { if (op == '+' || op == '-') { return 1; } else if (op == '*' || op == '/') { return 2; } else { return 0; } } string infixToPostfix(string infix) { stack<char> optr; string postfix = ""; for (int i = 0; i < infix.length(); i++) { char ch = infix[i]; if (isdigit(ch)) { postfix += ch; } else if (ch == '(') { optr.push(ch); } else if (ch == ')') { while (optr.top() != '(') { postfix += optr.top(); optr.pop(); } optr.pop(); } else { while (!optr.empty() && priority(ch) <= priority(optr.top())) { postfix += optr.top(); optr.pop(); } optr.push(ch); } } while (!optr.empty()) { postfix += optr.top(); optr.pop(); } return postfix; } int main() { string infix = "1+(2-3)*4+10/5"; string postfix = infixToPostfix(infix); cout << postfix << endl; return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值