只允许一位数的运算,确实是“简单”计算器
# 题目描述: 实现一个简单的计算器,输入一个包含圆括号、加减乘除、求余等符号组成的算术表达式字符串,输出该算术表达式的值。要求:
(1)系统至少能实现加、减、乘、除、求余等运算;
(2)利用栈实现并将表达式结果输出。
一、算法思想
模仿计算器的思想,对输入的中缀表达式转化为后缀表达式在计算。
在转化的时候使用一个栈用于存储操作符。
在使用后缀表达式计算的时候使用一个栈用来存储数字
对于后缀表达式每次遇到数字就压到栈中,遇到操作数就从栈中弹出两个数字运算然后在将结果压到栈中。最后栈顶的元素就是表达式的结果。
二、代码
#include<bits/stdc++.h>
using namespace std;
//得到操作符的算数优先级
int Get_priority(char c) {
if (c == '+' || c == '-')return 1;
if (c=='*'||c=='/'||c=='%')return 2;//这三个运算符的优先级一样
return 0;
}
//判断是否为操作符
bool is_operator(char c) {
if (c=='+'||c=='-'||c=='/'||c=='*'||c=='%') return true;
return false;
}
//中缀转后缀表达式
string min2end(string str) {
stack<char> s2;//操作符栈
string ans = "";
//迭代器
for(char temp: str){
if (temp>='0'&&temp<='9') {
ans += temp;
}
else if(is_operator(temp)) {
if (s2.empty()) s2.push(temp); //栈空直接入栈
//优先级大于栈的最上面一个元素就直接进栈
else if (Get_priority(temp)>Get_priority(s2.top())) {
s2.push(temp);
}//否侧就将最上面的操作符填在ans的尾部
else if(Get_priority(temp)<=Get_priority(s2.top())) {
ans += s2.top();
s2.pop();
s2.push(temp);
}
}
if (temp=='(') {
s2.push(temp);
}
//遇到右括号就将左括号之后的操作符都接在ans的尾部
if (temp==')') {
while (s2.top()!='(') {
ans += s2.top();
s2.pop();
}
s2.pop();
}
}
while (!s2.empty()) {
ans += s2.top();
s2.pop();
}
return ans;
}
int Get_ans(string str) {
stack<int> s;
int index = 0;
//迭代器
for (char c : str) {
char c = str[index];
if (c <= '9' && c >= '0') {
s.push(c - '0');
}
else {
//遇到操作符就弹出来两个数进行运算,第二个弹出的数在第一个弹出的数前面
int a = s.top(); s.pop();
int b = s.top(); s.pop();
if (c == '+') s.push(a + b);
else if (c == '-') s.push(b - a);
else if (c == '*')s.push(b * a);
else if (c == '/')s.push(b / a);
else if (c == '%')s.push(b % a);
}
index++;
}
return s.top();
}
int main() {
string text = "1+2*3%2";
cout<<Get_ans(min2end(text));
return 0;
}
总结
栈的应用的经典例题,通过这题能够理解栈的应用,函数的调用也是栈的思想,在一个函数被调佣的时候就会想函数名压栈,函数运行结束就会将函数名弹栈。如果函数一直被调用没有结束就会出现栈溢出,经典就是递归的时候在栈溢出前没有得出答案。栈溢出属于错误。迭代器相比于不同的for循环减少了判断的步骤,能够更有效率