后缀表达式进行表达式求值的代码并实现_C++ 双栈实现表达式求值

a34d41d6daba8fec8be1f7b60f26dae2.png

C++双栈实现表达式求值

好程序就是用更少的代码实现更多的功能,该程序无疑做到了这一点。

但在使用更少的代码实现功能的同时,代码也更难让人理解。

程序中的算法与思路均来源于网络,但我知道是伟大的计算机前辈们发明了它。

我经过了很长时间的调试和画图才理解并仿照出了这个程序,但在极少数情况,仍会出现在我意料之外的计算错误,由于此时的表达式较长,我也没有再去深究。

功能:

该程序实现了输入一个表达式求值的功能,支持多重小括号、+-*/%运算,最终结果为一个整数,仅支持正整数运算,输入不正确的数值会导致最终计算结果错误。

运行效果:

8a46ec84ac3f9d7ae9d89ad1999f2fee.png

f9253fa9a748d82911a48919c73587a4.png

编译环境:Windows VS2019

思路:

输入的表达式保存到字符串中,通过遍历该字符串,找到字符串中的数字和运算符,再根据规则处理他们。

注意:

该程序仅可以计算正整数的表达式,且最终结果非百分百正确,仅可用于学习参考。

代码:

#include <iostream>
#include "mystack.h"
using namespace std;

class Calcu
{
private:
	string expr;			//用于输入的字符串
	int num_1 = 0,num_2 = 0;//记录运算数
	char oper = 0;			//记录运算符
	Stack<int> numstack;	//数据栈
	Stack<char> operstack;	//运算符栈
	bool sign = false;		//第一次标记
	int strsize = 0;		//存储表达式的长度

	//判断运算符优先级函数
	inline int Priority(char oper)
	{
		switch (oper)
		{
		case '+':
		case '-':
			return 1;
		case '*':
		case '/':
		case '%':
			return 2;
		case '(':
		case ')':
			return 0;	//小括号优先级为0为程序必要
		case 0:
		default:
			return -1;	//程序必要
		}
	}

public:
	//计算主函数
	void Function()
	{
		//输入表达式
		cout << endl << "请输入要计算的表达式:(0不会参与运算)" << endl << endl;
		cin >> expr;

		//主循环
		strsize = expr.size();		//记录字符串的长度
		for (int i = 0; i < strsize; i++)
		{
			//转换数字必要
			num_1 = 0;
			num_2 = 0;

			//将一个或多个数字字符转换为一个数
			while (expr[i] >= '0' && expr[i] <= '9')
			{
				num_1 = expr[i] - '0';
				num_2 = num_2 * 10 + num_1;
				i++;
			}
			
			//将当前数入栈(0无法入栈)
			numstack.push(num_2);

			//如果符号栈为空,则符号直接入栈
			if (operstack.empty())
			{
				operstack.push(expr[i]);
				continue;
			}

			//如果当前运算符优先级高于栈顶元素的优先级(下标越界的不存在的运算符优先级为最低),或为左括号,则将该符号入栈
			if (Priority(expr[i]) > Priority(operstack.gettop()) || expr[i] == '(')
			{
				operstack.push(expr[i]);
				continue;
			}
			
			//当前符号优先级小于等于栈顶运算符优先级执行运算循环
			while (Priority(expr[i]) <= Priority(operstack.gettop()))
			{
				//将栈中的两个数据取出
				num_1 = numstack.pop();
				num_2 = numstack.pop();

				//根据运算符号计算不同的算式
				switch (operstack.pop())	//运算符栈出栈,保存符号
				{
				case '+':
					num_2 += num_1; break;
				case '-':
					num_2 -= num_1;	break;
				case '*':
					num_2 *= num_1; break;
				case '/':
					num_2 /= num_1; break;
				case '%':
					num_2 %= num_1;
				}

				numstack.push(num_2);				//将计算结果压栈

				if (expr[i] == ')')					//字符位为)时 (出栈,i++
				{
					operstack.pop();				
					i++;
				}

				if (operstack.gettop() == '(')		//运算符栈顶为(时,入栈其他字符
					break;

				if(operstack.empty())				//当符号栈为空时退出循环
					break;
			}

			//不要忘记将数压入栈中后,还要将这个数后面的运算符也压入栈
			if (i < strsize)
				operstack.push(expr[i]);
		}

		//最后输出计算结果:
		//cout << num_2 << endl;
		cout << "结果:" << numstack.pop() << endl << endl;
	}

};

//主函数
int main()
{
	system("title 双栈计算器");          //设置标题

	while (true) Calcu().Function();    //计算函数

	return 0;
}

//1+3%4-4*(4+5*(6+7-3*(4-5*(6-8)+8)-6)-14)+2*(8-(3+1-1))+12*(15+12)+800-(10*10)-1258+100

不足之处:

该程序功能较少,且计算结果在特定情况下会出错,没有实际意义。


感谢大家的支持。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值