/*
2017.3.5 hfut-MrQ_zh
注意符号从栈中取出来时顺序改变了除法减法顺序改变
还有优先级判断...
*/
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxlen=1000;
enum error_code{success,underflow,overflow
};
class stack{
public:
stack();
bool empty();
bool full();
int get_top(char &x); //两个栈一个符号一个数字
int get_top(int &x);
int push(const char x);
int push(const int x);
int pop();
private:
int count;
char data[maxlen];
int data2[maxlen];
};
stack::stack(){
count=0;
}
bool stack::empty(){
return 0 == count;
}
bool stack::full(){
return count == maxlen;
}
stack::get_top(char &x){
if(empty()){
return underflow;
}
else{
x = data[count-1];
return success;
}
}
stack::get_top(int &x){
if(empty()){
return underflow;
}
else{
x = data2[count-1];
return success;
}
}
stack::pop(){
if(empty()){
return underflow;
}
else{
count--;
return success;
}
}
stack::push(const char x){
if(full()){
return overflow;
}
else{
data[count]=x;
count++;
return success;
}
}
stack::push(const int x){
if(full()){
return overflow;
}
else{
data2[count]=x;
count++;
return success;
}
}
bool isoperator(char x){ //判断是否是数学符号
switch(x){
case '+': return true; break;
case '-': return true; break;
case '*': return true; break;
case '/': return true; break;
case '(': return true; break;
case ')': return true; break;
case '#': return true; break;
default:return false;
}
}
int priority(char oper1,char oper2) //判断优先级
{
int pri;
switch(oper1)
{
case '+':
case '-':
if(oper2=='('||oper2=='#') pri=-1;
else pri=1;
break;
case '*':
case '/':
if(oper2=='+'||oper2=='-'||oper2=='('||oper2=='#') pri=-1;
else pri=1;
break;
case '(':
pri=-1;
break;
case ')':
if(oper2=='(') pri=0;
else pri=1;
break;
case '#':
if(oper2!='#') pri=1;
else pri=-1;
}
return pri;
}
int calculate(int x,int y,char oper){
//cout<<oper<<endl;
switch(oper){
case '+':return x+y;break;
case '-':return y-x;break;
case '*':return x*y;break;
case '/': if(x!=0){
return y/x;
break;
}
else{
cout<<"除数不能为零";
}
}
}
int NumberSplicing(char ch[]) //字符转数字
{
int temp =0; //临时拼接的数值
static int len = 10;
for(int n=0;n<strlen(ch);n++)
{
char c = ch[n];
c-='0';
temp = temp *10 + c;
}
return temp;
}
int solve(char text[]){
stack data_sym; //符号栈
stack data_num; //数字栈
int num1,num2;
char top_char; //符号栈顶临时变量
char temp_c;
char temp_num[maxlen]; //数字字符的数组
int flag=0,i=1,j=0; //warning->i=1
int num=0;
data_sym.push('#');
//初始化
temp_c=text[i++];
while(temp_c!='#'||top_char!='#'){
if(isoperator(temp_c)){ //先判断是不是运算符
if(flag){ //把数字连接起来
temp_num[j]=0;//截断
j=0;
num=NumberSplicing(temp_num);
data_num.push(num);
num=0;
flag=0;
}
char oper;
int t;
switch(priority(temp_c,top_char)){
case 1:
data_sym.get_top(oper);
data_sym.pop();
data_num.get_top(num1);
data_num.pop();
data_num.get_top(num2);
data_num.pop();
t=calculate(num1,num2,oper);
data_num.push(t);
break;
case 0: //只有左右括号这种
data_sym.pop();
temp_c=text[i++];
break;
case -1:
data_sym.push(temp_c);
temp_c=text[i++];
}
}
else{ //是数字->要判断是几位数字
temp_num[j++]=temp_c;
flag=1;
temp_c=text[i++];
}
data_sym.get_top(top_char);
}
data_num.get_top(num);
cout<<num<<endl;
}
int main(){
char text[maxlen]="#12+5*(3+2)*6/2-4#";
// char text[maxlen];
// cout<<"欢迎使用简单计算器...请用#为表达式开头和结尾"<<endl;
// cin>>text;
solve(text);
return 0;
}
表达式计算(栈/c++)
最新推荐文章于 2023-09-24 10:20:05 发布