通过栈的操作实现简单的计算器
首先定义两个栈,一个叫s_num用来存放操作数,另一个叫s_opt用来存放操作符。
再定义一个字符数组用来存放输入的表达式,初始化为0;
当表达式的字符不为‘/0’时,或者操作符栈中不为空的时候,就要一直执行程序!
在执行的时候做两个判断,输入的不是数字就是操作符,当输入数字的时候进栈就可以了,并且i++,遍历下一个。
当遇到操作符时:有三种情况
一、入栈的情况:(入栈结束后,i++,遍历下一个输入字符)
1.操作符栈为空的时候。
2.操作符的优先级大于栈顶元素的时候。
3.当栈顶元素为’(‘时,并且输入不为')'时。
二、出栈不计算(结束后,i++,遍历下一个字符)
1.操作符出栈不计算的情况只有一种情况就是“( ”操作符出栈的时候。
当输入为“ )”时,并且栈顶为“( ”时,就是两个符号相遇时,出栈“( ”并不计算。
三、出栈计算(计算完将数字存入s_num中就可以了,不需要遍历下一个字符)
将输入的字符与栈顶元素比较,满足情况的话将栈顶元素出栈,并取num栈中的数字进行运算,这是不需要i++,遍历下一个输入字符,break后再将输入的字符与栈顶元素比较,判断是入栈还是出栈!!!
1.输入的操作符为"/0"的时候,并且操作符栈不为空的时候,要将操作符中的所有元素出栈运算。
2.输入的操作符优先级小于或等于栈顶元素时。
3.当输入的字符为“ )”时,并且栈顶元素不为“( ”时。
#include <iostream>
#include <stack>
using namespace std;
stack<char> s_opt;//操作符栈
stack<int> s_num;//数据栈
int Priority(char ch){//判断优先级
switch(ch){
case '(':
return 3;
case '*':
case '/':
return 2;
case '+':
case '-':
return 1;
default:
return 0;
}
}
int main(){
char opt[1024] = {0};
int i = 0, tmp = 0, num1 = 0, num2 = 0;
cout << "Please input: " << endl;
cin >> opt;
while(opt[i] != '\0' || s_opt.empty() != true){
if(opt[i] >= '0' && opt[i] <= '9'){
tmp = tmp * 10 + opt[i] - '0';
i++;
if(opt[i] > '9' || opt[i] < '0'){
s_num.push(tmp);
tmp = 0;
}
}
else{
if((opt[i] == ')') && (s_opt.top() == '(')){
s_opt.pop();
i++;
continue;
}
if((s_opt.empty()) == true || (Priority(opt[i]) > Priority(s_opt.top()))||(s_opt.top() == '(' && (opt[i] != ')'))){
s_opt.push( opt[i]);
i++;
continue;
}
if( ((opt[i] == '\0') &&( s_opt.empty() != true)) || ( (opt[i] == ')') && (s_opt.top() != '(') )||(Priority(opt[i]) <= Priority(s_opt.top())) ){
char ch = s_opt.top();
s_opt.pop();
int num1,num2;
switch(ch){
case'+':
num1 = s_num.top();
s_num.pop();
num2 = s_num.top();
s_num.pop();
s_num.push(num1 + num2);
break;
case'-':
num1 = s_num.top();
s_num.pop();
num2 = s_num.top();
s_num.pop();
s_num.push(num2 - num1);//1 2
break;
case'*':
num1 = s_num.top();
s_num.pop();
num2 = s_num.top();
s_num.pop();
s_num.push(num1 * num2);
break;
case'/':
num1 = s_num.top();
s_num.pop();
num2 = s_num.top();
s_num.pop();
s_num.push(num1 / num2);
break;
}
}
}
}
cout << s_num.top() << endl;
return 0;
}