可以使用括号,但只能进行个位数输入
输入样例:5*(2+3)
#include <iostream>
#include <stack>
#include <queue>
#include <string>
#include <sstream>
using namespace std;
#define max 200
void get_input(queue<char> str[])
{
/*存储原算术表达式*/
printf("*****************************************\n");
printf("*输入一个求值的表达式,以#结束*\n");
printf("***只能计算0-9的整数四则运算***\n");
printf("算数表达式:");
/*获取用户输入的表达式*/
do
{
char ch;
cin >> ch;
str->push(ch);
} while (str->back() != char('#'));
cout << "输入完毕!" << endl;
}
void mid2backExchange(queue<char> str[], queue<char> backstr[])
{
char ch;
stack<char> strStack;
int i = 0;
ch = str->front();
str->pop();
do //当算式没有到尾端的时候,执行该算法
{
switch (ch)
{
case '(': //左括号-->入栈
strStack.push(ch);
break;
case ')': //右括号
while (strStack.top() != '(') //当栈顶不是'('时一直出栈,并输出到后缀表达式
{
backstr->push(strStack.top());//入队
strStack.pop();
}
strStack.pop();// '('出栈
break;
case '+': //加减号-->
case '-':
while (!strStack.empty() && strStack.top() != '(')//当栈不为空,且栈顶不为左括号,意味着栈顶运算优先,因为加减运算优先等级最低,
{ //此时应把栈顶更为优先的运算符全部while循环出栈,再把当前的加减号入栈
backstr->push(strStack.top());//pop出栈顶的运算符,直到栈顶为左括号或者为空
strStack.pop();
}
strStack.push(ch); //加减符入栈
break;
case '*': //乘除号
case '/':
while (!strStack.empty() && (strStack.top() == '*' || strStack.top() == '/'))//栈顶也为乘除号时,栈顶优先,则栈顶出栈,否则当前乘除号优先,则跳出while,并当前乘除号入栈
{
backstr->push(strStack.top());
strStack.pop();
}
strStack.push(ch);
break;
case ' '://空格符号直接跳过
break;
default://数字-->直接输出到后缀表达式
if (ch >= '0' && ch <= '9')
{
backstr->push(ch);
}
break;
} //switch结束
ch = str->front();
str->pop();
} while (ch != '#');
while (!strStack.empty())
{
backstr->push(strStack.top());
strStack.pop();
}
backstr->push('#');
//cout << "后缀表达式:";
//while (backstr->front() != '#')
//{
// cout << backstr->front();
// backstr->pop();
//}
//return 0;
}
double calc_xy(double x, double y, char ch) {
switch (ch) {
case '+': return x + y;
case '-': return x - y;
case '*': return x * y;
case '/':
//遇到除数为0的情况-->报错
if (y == 0)
{
cout << "Error: Divide by 0"<< endl;
exit(0);
}
return x / y;
}
}
//1.遇到数字-->入栈
//2.遇到运算符-->两个数字出栈,相运算,并入栈
void output(queue<char> backstr[])//计算后缀
{
stack<double> calStack;
int t = 0;
char s;
while (1)
{
s = backstr->front();//头出
backstr->pop();
if (s == '#') break;//遇到#符号结束读入,并开始计算
if (s != '+' && s != '-' && s != '*' && s != '/') //数字-->入栈
{
int n = s - '0';
calStack.push(n);
}
else //运算符-->弹出两个数,计算并入栈
{
double x = calStack.top(); calStack.pop();//先拿出一个元素
////如果拿了一个元素之后就没有元素了,那么就出错了,打印已拿出栈顶元素x
//if (sta.empty()) {
// cout << "Expression Error: " << x << endl;
// exit(0);
//}
double y = calStack.top(); calStack.pop();//拿出第二个元素
double res = calc_xy(y, x, s);//计算值,并push到栈中
calStack.push(res);
}
}
if (calStack.size() == 1) //上面的while循环跳出-->后缀表达式已计算完毕-->若栈中元素只有一个,打印x,计算成功
cout << calStack.top() << endl;
else //否则-->出错,打印已拿出栈顶元素x
{
cout << "Expression Error: " << calStack.top() << endl;
exit(0);
}
}
int main() {
queue<char> str[max];
queue<char> backstr[max]; /*存储后缀表达式*/
get_input(str);
mid2backExchange(str, backstr);
output(backstr);
return 0;
}