【栈】中缀表达式求值(简易计算器)

这里介绍中缀表达式求值的两种方法:

(1)、先将中缀表达式转化为后缀表达式,再利用后缀表达式求值算法计算,这里可看之前的文章,中缀表达式转化为后缀表达式后缀表达式求值

(2)、利用栈来实现,这里需要两个栈:数据栈和操作符栈,依次扫描字符串,遇到数据就压入数据栈中,遇到操作符,则判断其与操作符栈栈顶元素的优先级,这里可参考文章里的判断方法:中缀表达式转化为后缀表达式

方法(2)的具体代码如下:(代码多位数运算存在bug,暂时没修改,大佬可以评论区修改)

#include<bits/stdc++.h>
using namespace std;
int yxj(char c)
{
	if (c == '-' || c == '+')
		return 1;
	if (c == '*' || c == '/')
		return 2;
	return 3;
}
int jisuan(int a, char c, int b)
{
	switch (c) {
	case '+':return a + b;
	case '-':return a - b;
	case '*':return a * b;
	case '/':return 1.0*a / b;
	}
}
void duoweishu(stack<int> &s_number, int &flag) //将输入的多位数转化处理
{
	int n=flag;
	for (int i = 1; i <= n; i++)
	{
        int right = s_number.top();
		s_number.pop();
		int left = s_number.top();
		s_number.pop();
		s_number.push(right+left*pow(10,i));
		flag--;
	}
}
void yunsuan(stack<int>& s_number, char c) //将两个操作数出栈运算,结果继续入栈
{
	int right = s_number.top();
	s_number.pop();
	int left = s_number.top();
	s_number.pop();
	s_number.push(jisuan(left, c, right));
}
int panduan(stack<int> &s_number, stack<char> &s_str, char c)
{
	if(s_str.empty())
	{
        s_str.push(c);
		return 0;
	}	
	else
	{
		if (c == '(')
		{
			s_str.push(c);
			return 0;
		}
		else if (c == ')')
		{
			while (s_str.top() != '(')
			{
				yunsuan(s_number, s_str.top());
				s_str.pop();
			}
			s_str.pop();//将( 出栈
		}
		else
		{
			if (yxj(c) > yxj(s_str.top()))
			{
				s_str.push(c);
				return 0;
			}
			else
			{
				if (s_str.top() != '(')
				{
	                yunsuan(s_number, s_str.top());
					s_str.pop();
					return panduan(s_number, s_str, c);
				}
				if (s_str.top() == '(')
				{
					s_str.push(c);
					return 0;
				}
			}
		}
	}
}
int main()
{
	string s;
	stack<int> s_number;//数据栈
	stack<char> s_str;//操作符栈
	while (cin >> s)
	{
		int flag = 0;//用来判断数字是个位数还是多位数
		for (char c : s)
		{
			if (isdigit(c) != 0)//c是数字
			{
                s_number.push(c - '0');//将字符c转换为数字c
				flag++;
			}
			else//c是操作符
			{
				flag--;
				if (flag != 0)
					duoweishu(s_number, flag);
				panduan(s_number, s_str, c);
			}
		}
		while (!s_str.empty())
		{
			duoweishu(s_number, flag);
			yunsuan(s_number, s_str.top());
			s_str.pop();
		}
		cout << s_number.top() << endl;
		s_number.pop();
	}
	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值