[数据结构]利用堆栈求解算术表达式

c语言版的,可以运算包括小数点存在的情况

#include<iostream>
#include<stdio.h>
#define MAXSIZE 100
using namespace std;

struct SqStack{
    double *base;
    double *top;
    double SatckSize;
}s_val;

struct SqStack_ter{
    double *base;
    double *top;
    double SatckSize;
}s_ter;

template <class T>
void InitStack(T &S)
{
    S.base=new double[MAXSIZE];
    if(!S.base) cout<<"error"<<endl;
    S.top=S.base;
    S.SatckSize=MAXSIZE;
}

double GetTop_val()
{
    if(s_val.top!=s_val.base)
        return *(s_val.top-1);
}

char GetTop_ter()
{
    if(s_ter.top!=s_ter.base)
        return *(s_ter.top-1);
}

void Push_val(double e)
{
    if(s_val.top-s_val.base==s_val.SatckSize) cout<<"error"<<endl;
    *s_val.top++=e;
}


void Pop_val(double &e)
{
    if(s_val.top==s_val.base) cout<<"error"<<endl;
    e=*--s_val.top;
}

void Push_ter(char &e)
{
    if(s_ter.top-s_ter.base==s_ter.SatckSize) cout<<"error"<<endl;
    *s_ter.top++=e;

}


void Pop_ter(char &e)
{
    if(s_ter.top==s_ter.base) cout<<"error"<<endl;
    e=*--s_ter.top; 
}

double calculate(double b, char theta, double a)   //计算b theta a  
{  
    switch (theta)  
    {  
    case '+':  
        return (double)b + a;  
    case '-':  
        return (double)b - a;  
    case '*':  
        return (double)b * a;  
    case '/':  
        return (double)b / a;  
    default:  
        break;  
    }  
} 

int getIndex(char theta)   //获取theta所对应的索引  
{    
    char B[7]={'+','-','*','/','(',')','#'};
    int i=0;
    while(theta !=B[i]) {i++;} 
    return i;  
} 

char getPriority(char theta1, char theta2)   //获取theta1与theta2之间的优先级  
{  
    const char priority[][7] =     //运算符间的优先级关系  
    {  
        { '>','>','<','<','<','>','>' },  
        { '>','>','<','<','<','>','>' },  
        { '>','>','>','>','<','>','>' },  
        { '>','>','>','>','<','>','>' },  
        { '<','<','<','<','<','=','0' },  
        { '>','>','>','>','0','>','>' },  
        { '<','<','<','<','<','0','=' },  
    };  

    int index1 = getIndex(theta1);  
    int index2 = getIndex(theta2);  
    return priority[index1][index2];  
}  

double getAnswer(){
    InitStack(s_val);
    InitStack(s_ter);
    char tep='#';
    Push_ter(tep);
    bool isNum=false;
    double result=0;
//  char *p=new char[100]; 
//  cin>>p;这是另一种存储方法,先把表达式存放在数组里,然后再依次求解 
    int i=0;

    char c=getchar();
    while(c!='#')
    {
        if(isdigit(c))
        {
            if(isNum)
            {
                //如果之前的数是数字,就要进位 
                double a;
                Pop_val(a);
                Push_val(double(a*10+(c-'0')));
            }
            else
            {
                //如果之前不是数字,直接push 
                Push_val(double((c-'0')));
                isNum=true;
            }
            //i++;
            c = getchar();  
        }
        else
        {
            isNum=false;
            char a;
            //Pop_ter(s_ter,a);
            a=GetTop_ter();
            switch(getPriority(a,c))//获取栈顶元素与当前操作符的优先级 
            {
                case '>':
                    char theta; 
                    Pop_ter(theta);     //运算符出  
                    double a_num;
                    Pop_val(a_num);  //操作数出栈
                    double b_num; 
                    Pop_val(b_num);  //操作数出栈
                    Push_val((calculate(b_num, theta, a_num)));  
                    // c = getchar();  当读到需要计算的符号时,运算符出栈,两个操作数出栈,然后计算后将结果push栈中。 
                    //这里不再继续读char,而其它情况需要再读char的原因是: 
                    //当大于的情况时,当前c一定不为'#',所以不用再读,就可以返回最上面的while()循环 
                    break;
                case '<':
                    Push_ter(c);
                    c = getchar();  
                    break;
                case '=':
                    char temp;
                    Pop_ter(temp);
                    c = getchar();  
                    break;                          
            }
        }
    }   
    return calculate(*(s_val.top-2),GetTop_ter(),GetTop_val()); 
    //按此思路计算,堆栈中的top-1与top-2存放着最后两个未处理的数
    //需要做次计算才能得到最终的结果,具体原因是因为 当c读到#时,s_val中仍存放着两个未处理的数字
    //而s_ter中仍存放着最后一个操作符。 
}

int main(){
    double ans = getAnswer();   
    cout <<"答案"<<ans<< endl; 
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值