描述
实现一个算法,可以进行任意非负整数的加减乘除组合四则运算。
请注意运算符的优先级。
输入
请输入一行算式,使用空格分隔数字与运算符。
数字为任意非负整数,运算符为+ - * /,不考虑括号。
输出
输出算式的运算结果。如果是小数,请向下取整(包含中间步骤结果)。 如果出现“除0异常”,输出err。
输入样例
3 + 5
12 + 45 / 9
1 / 2
1 / 0
12 + 34 * 56 - 78
输出样例
8
17
0
err
1838
解析:这一题是关于非负整数的四则运算,不包括"("和")"。整体思路是把输入的中缀表达式转化为后缀表达式,然后通过后缀表达式求值。
中缀表达式TO后缀表达式
(这个思路是包含括号运算符的)
利用两个队列in,suf和一个栈ope:其中in存放中缀表达式,suf存放后缀表达式,ope存放运算符
从左往右遍历中缀表达式,如果遇到数字,则放入suf中,如果遇到操作符,则放入ope中。在放操作符的时候有一定的规则,如果栈为空或栈顶元素为(,则直接压栈。如果是(,也直接压栈;如果栈顶元素为普通操作符,则比较优先级,如果待压栈的操作符比栈顶操作符优先级高,则直接压栈,否则将ope中的栈顶元素出栈,并压入suf中,再接着比较ope栈顶元素的优先级。如果遇到),则依次弹出ope栈顶的运算符,并压入suf,直到遇到左括号为止,此时将这一对括号丢弃。最后将ope中剩余的运算符依次弹出并压入suf,便得到了后缀表达式。(注意:等号的优先级最低,因为要到最后才进行赋值操作)
大致过程.png
代码如下,这一题写的代码比较笨,如果运算符种类比较多的话应该为每个运算符设置优先级。
//中缀转化为后缀
void intosuf (queue &in , queue &suf)
{
//存放运算符
stack ope;
for(; !in.empty() ; in.pop())
{
auto c = in.front();
if(c != "+" && c != "-" && c != "*" && c != "/")
{
suf.push(c);
}
else if((c == "+" || c == "-" ) && !ope.empty())
{
while((c == "+" || c == "-" ) && !ope.empty())
{
suf.push(ope.top());
ope.pop();
}
ope.push(c);
}
else if(ope.empty())
{
ope.push(c);
}
else if((c == "*" || c == "/" ) && !ope.empty() && (ope.top() == "+" || ope.top() == "-" ))
{
ope.push(c);
}
else if((c == "*" || c == "/" ) && !ope.empty() && (ope.top() == "*" || ope.top() == "/" ))
{
while((c == "*" || c == "/" ) && !ope.empty() && (ope.top() == "*" || ope.top() == "/" ))
{
suf.push(ope.top());
ope.pop();
}
ope.push(c);
}
}
while(!ope.empty())
{
suf.push(ope.top());
ope.pop();
}
}
利用后缀表达式求值
后缀表达式的求值规则为:从左到右扫描后缀表达式,如果遇到操作数,将其压入栈中,如果遇到操作符,则从栈中弹出两个操作数,计算结果,然后把结果入栈,直到遍历完后缀表达式,则计算完成,此时的栈顶元素即为计算结果。
没有写额外的函数来封装,直接写在main里面了
int main()
{
string input;
while(getline(cin,input))
{
//分别放中缀后缀表达式
queue infix;
queue suffix;
//运算用到的栈
stack calculation;
//出错标志
int err = 0;
stringstream ss(input);
string item;
while(getline(ss,item,' '))
{
infix.push(item);
}
intosuf(infix,suffix);
for(; !suffix.empty() ; suffix.pop())
{
auto c = suffix.front();
if(c != "+" && c != "-" && c != "*" && c != "/")
{
calculation.push(c);
}
else if(c == "+")
{
int i = stoi(calculation.top());
calculation.pop();
int j = stoi(calculation.top());
calculation.pop();
calculation.push(to_string(i+j));
}
else if(c == "-")
{
int i = stoi(calculation.top());
calculation.pop();
int j = stoi(calculation.top());
calculation.pop();
calculation.push(to_string(j-i));
}
else if(c == "*")
{
int i = stoi(calculation.top());
calculation.pop();
int j = stoi(calculation.top());
calculation.pop();
calculation.push(to_string(i*j));
}
else if(c == "/")
{
int i = stoi(calculation.top());
calculation.pop();
int j = stoi(calculation.top());
calculation.pop();
if(i == 0)
{
err = 1;
break;
}
calculation.push(to_string(j/i));
}
}
if(err == 0)
{
cout<
}
else
{
cout<
}
}
return 0;
}