用栈计算中缀表达式(具体详细,还包含getchar的用法)

本文详细介绍了如何利用两个栈,一个存储数字,一个存储运算符,来计算中缀表达式。关键步骤包括判断字符是数字还是运算符,比较运算符优先级,以及执行相应的计算。在处理过程中,特别提到了处理运算符栈和数字栈的逻辑,以及解决getchar()的缓冲区问题和循环条件的设定。

标题## 用栈计算中缀表达式

中缀表达式也就是我们常说的普通数学表达式,那么怎么用栈来计算呢?请听我一一分解。
我们基本的思路是用两个栈来分别存储表达式中的数字和运算符,在通过有序的出栈来进行计算。(我用OPTR代表运算符栈,OPND代表运算数字栈)
方便判断表达式的结束,我会在运算符栈第一个元素和表达式后面加一个#
在此之前,先要把基础的功能函数写出来
1.判断是数字还是运算符

//判断计算表达式中下一个字符是数字还是运算符 ,返回0是代表运算数字,返回1代表运算符号 
int in(char ch)
{
   
   
	switch(ch)
	{
   
   
		case '0': case '1': case '2': case '3': case '4':
	  	case '5': case '6': case '7': case '8': case '9':
	  		return 1;
	  		break;
	  	default: 
	  		return 0;
	}
}

2.比较运算符优先级的函数(这个是最关键的)
在给出代码之前,我先给一张对比表给大家看看
在这里插入图片描述
图片中的θ2表示运算符栈的栈顶元素,θ1表示读取到的运算符
大于号表示θ2的优先级高于θ1,小于就相反,等于就优先级相等
(下面代码我就用1,0,-1依次代表大于,等于,小于)

int precede(char topch,char ch)
{
   
   
	if(topch=='+'||topch=='-')
	{
   
   
		if(ch=='+'||ch=='-'||ch=='#'||ch==')')
		{
   
   
			return 1; 
		}
		else
		{
   
   
			return -1;
		} 
	}
	else if(topch=='*'||topch=='/')
	{
   
   
		if(ch=='(')
		{
   
   
			return -1;
		}
		else
		{
   
   
			return 1;
		} 
	}
	else if(topch=='('
### 如何使用计算中缀表达式 为了评估中缀表达式,可以采用两个的方法:一个用于操作数,另一个用于运算符。这种方法能够有效地处理不同优先级的操作并支持括号结构。 #### 方法概述 通过遍历输入字符串中的字符,根据遇到的不同类型的符号采取不同的动作。当遇到数字时将其压入操作数;当遇到运算符时,则依据当前运算符与上一运算符之间的关系决定是否执行相应的算术运算,并更新运算符顶元素。对于左括号`(`直接放入运算符内等待匹配右括号`)`,而一旦发现右括号则立即触发内部所有可能的计算直到最近的一个左括号被弹出为止[^1]。 #### 实现细节 下面给出了一段具体的实现代码: ```cpp #include <iostream> #include <stack> #include <cctype> using namespace std; // 判断是否为运算符 bool isOperator(char c){ return (!isalpha(c) && !isdigit(c)); } // 获取运算符权重 int getPriority(char C){ if(C == '-' || C == '+') return 1; else if(C == '*' || C == '/') return 2; return 0; } // 执行基本运算 int calculate(int op1, int op2, char oper){ switch(oper){ case '+': return op1 + op2; case '-': return op1 - op2; case '*': return op1 * op2; case '/': return op1 / op2; } return -1; // 错误情况返回-1 } // 将中缀表达式转换成后缀表达式再解 void evaluateExpression(string& exp){ stack<int> values; stack<char> ops; for(auto i=0;i<exp.size();i++){ // 如果是空白跳过 if(exp[i] == ' ') continue; // 数字累加到oprand变量里 else if(isdigit(exp[i])){ long oprand = 0; while(i < exp.size() && isdigit(exp[i])) oprand = (oprand*10)+(exp[i++]-'0'); values.push(oprand); } // 遇到'('就推入ops堆 else if(exp[i]=='(') ops.push(exp[i]); // 当遇到')', 计算整个括号内的 else if(exp[i]==')'){ while(!ops.empty()&&ops.top()!='('){ int val2 = values.top(); values.pop(); int val1 = values.top(); values.pop(); char op = ops.top(); ops.pop(); values.push(calculate(val1,val2,op)); } // 移除'(' if(!ops.empty()) ops.pop(); } // 运算符处理逻辑 else{ while(!ops.empty() && getPriority(ops.top()) >= getPriority(exp[i])) { int val2 = values.top(); values.pop(); int val1 = values.top(); values.pop(); char op = ops.top(); ops.pop(); values.push(calculate(val1,val2,op)); } ops.push(exp[i]); } } // 处理剩余项 while(!ops.empty()){ int val2 = values.top(); values.pop(); int val1 = values.top(); values.pop(); char op = ops.top(); ops.pop(); values.push(calculate(val1,val2,op)); } cout << "Result : "<<values.top()<<endl; } ``` 此程序首先定义了一些辅助函数来帮助解析和计算表达式的各个部分。接着,在主循环中按照上述策略逐步构建起最终的结果。最后输出得到的答案即为所给定中缀表达式的实际数结果[^2]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值