中缀转后缀并求值(简单计算器的核心)

中缀表达式转后缀表达式并求值

将中缀表达式转化为后缀表达式

string s 为原始表达式, stack S作为算术运算符栈, vector V存储后缀表达式结果

如果是算术运算符,分一下几种情况

(优先级说明:乘除的优先级,高于加减;’)'的优先级最低,‘(’的优先级最高)

  1. 如果算术运算符栈为空,直接将算术运算符入栈 S

  2. 如果栈顶元素的优先级低于算术运算符,直接入栈

  3. 如果栈顶元素的优先级高于算术运算符,栈S执行Pop操作,Pop出来的字符放入V,

    直到栈顶元素的优先级低于算术运算符或者栈为空,才将操作符入栈

    注意,’(’,’)‘不同于其他加减乘除运算符,遇到’(’,直接入栈(’(‘的出栈只会在遇到’)'的情况)

    遇到’)’,栈执行出栈操作,直到遇到’(’, 并把其pop出来,’)'本身不入栈

  4. 最后,把字符栈S中的元素依次Pop出来,放入V中,这时候V所存储的就是转化后的后缀表达式

通过后缀表达式,求出表达式的值

比如表达式(-1.23-1.22) x 3转化为后缀表达式为“-1.23#1.22#-#3#x”(#分隔每个元素)

定义一个double栈 S

  1. 遍历后缀表达式V

    • 如果元素为数字,直接入栈S

    • 如果元素为操作符, 栈S, pop出两个double操作数a, b利用操作符对a,b 进行算术运算,注意如果操作符是减号应该是 b-a, 把最终结果入栈S

  2. 最后栈只会有一个double数,这个数就是最后结果,pop出来。

c++代码

#include<iostream>
#include<stack>
#include<vector>
#include<cstdlib>
#include<limits.h>
using namespace std;

bool isNum(char ch) {
	if(ch >= '0' && ch <= '9') return true;
	else return false;
}

bool isOperate(char ch) {
	if(ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '(' || ch == ')')
	return true;
	else return false;
}

int level(char ch) {
	switch(ch) {
		case '(' :
			return 5;
		case '*' :
			return 4;
		case '/' :
			return 4;
		case '+' :
			return 3;
		case '-' :
			return 3;
		case ')':
			return 2;
	}
}
/*字符串转数字*/
double scd(string s) {
	if(s.length() == 0) return INT_MAX;
	
	bool flag = false;
	for(int i = 0; i < s.length(); i++) {
		if(i == 0 && s[i] == '-') continue;
		else if(s[i] == '.' && !flag) {
			if(i > 0 && isNum(s[i-1])) {
				flag = true;
				continue;
			}
			else return INT_MAX;
		}
		else if(isNum(s[i])) continue;
		else return INT_MAX;
	}
	
	double result = atof(s.c_str());
	return result;
}

 /*由中缀表达式得到后缀表达式, 向量V存储结果*/ 
vector<string> midToPost(string s) {
	stack<char> S; /*符号栈*/
	vector<string> V; /*后缀表达式*/
	int i = 0;
	while(i < s.length()) {
		if(isNum(s[i])) {
			string str = "";
			while(isNum(s[i]) || s[i] == '.') {
				str += s[i];
				i++;
			}
			V.push_back(str);
		}
		
		else if(isOperate(s[i])){
			/*负数情况*/ 
			if(s[i] == '-' && i > 0 && !isNum(s[i-1])) {
				string str = "-"; i++;
				while(isNum(s[i]) || s[i] == '.') {
					str += s[i]; i++;
				}
				V.push_back(str); 		
			}else{
				if(S.empty()){
					S.push(s[i]); i++; 
				}else {
					int initial = level(s[i]);
					if(initial == 2) {
						while(level(S.top()) != 5 && !s.empty()) {
							string str = "";
							str += S.top();
							V.push_back(str);
							S.pop();
						}
						if(S.top() == '(') S.pop(); i++;
					} else { 
						while(initial <= level(S.top()) && level(S.top()) != 5 && !S.empty()) {
							string str = "";
							str += S.top();
							V.push_back(str);
							S.pop();
						}
						S.push(s[i]); i++;
					}
				}
			}
		}
		else{
			cout << "表达式出错" << endl; 
			V.clear(); 
			return V;
		}
	}
	while(!S.empty()) {
		string str = ""; str += S.top();
		S.pop();
		V.push_back(str);
	}
	//for(int i = 0; i < V.size(); i++) cout << V[i] << "[]";
	return V;
}

/*后缀表达式得到最终结果*/
double getValue(vector<string> V) {
	stack<double> S;
	for(int i = 0; i < V.size(); i++) {
	/*操作运算符*/ 
		if(V[i].length() == 1 && isOperate(V[i][0])) {
			double a = 0, b = 0;
			if(!S.empty()) {
				a = S.top(); S.pop();
			}else return INT_MAX;
			
			if(!S.empty()) {
				b = S.top(); S.pop();
			}else return INT_MAX;
			
			switch(V[i][0]) {
				case '+':
					S.push(b+a);
					break;
				case '-':
					S.push(b-a);
					break;
				case '*':
					S.push(b*a);
					break;
				case '/':
					S.push(b/a);
					break;
				default:
					return INT_MAX;
			}
		}else {
			if(scd(V[i]) == INT_MAX) return INT_MAX;
			else S.push(scd(V[i]));
		}
	}
	if(S.empty()) return INT_MAX;
	
	double value = S.top();
	S.pop(); 
	return value;	
} 

int main() {
	string s; /*输入的字符串s*/
	vector<string> V; /*后缀表达式*/
	
    cin >> s; 
    V = midToPost(s);
    if(getValue(V) == INT_MAX) {
    	cout << "表达式出错" << endl; 
	}
	else cout << getValue(V) << endl;
} 
  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是C++中实现中缀后缀求值的示例代码: ```cpp #include <iostream> #include <stack> #include <string> #include <sstream> using namespace std; int getPriority(char op) { if (op == '+' || op == '-') return 1; else if (op == '*' || op == '/') return 2; else return 0; } string infixToPostfix(string infix) { stack<char> opStack; stringstream postfix; for (char c : infix) { if (isdigit(c)) { postfix << c; } else if (c == '(') { opStack.push(c); } else if (c == ')') { while (!opStack.empty() && opStack.top() != '(') { postfix << opStack.top(); opStack.pop(); } opStack.pop(); // 弹出左括号 } else { while (!opStack.empty() && getPriority(opStack.top()) >= getPriority(c)) { postfix << opStack.top(); opStack.pop(); } opStack.push(c); } } while (!opStack.empty()) { postfix << opStack.top(); opStack.pop(); } return postfix.str(); } int evaluatePostfix(string postfix) { stack<int> numStack; for (char c : postfix) { if (isdigit(c)) { numStack.push(c - '0'); } else { int operand2 = numStack.top(); numStack.pop(); int operand1 = numStack.top(); numStack.pop(); switch (c) { case '+': numStack.push(operand1 + operand2); break; case '-': numStack.push(operand1 - operand2); break; case '*': numStack.push(operand1 * operand2); break; case '/': numStack.push(operand1 / operand2); break; } } } return numStack.top(); } int main() { string infixExpression; cout << "请输入中缀表达式:"; cin >> infixExpression; string postfixExpression = infixToPostfix(infixExpression); cout << "后缀表达式:" << postfixExpression << endl; int result = evaluatePostfix(postfixExpression); cout << "计算结果:" << result << endl; return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值