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

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(struct SqStack &s)
{
    if(s.top!=s.base)
        return *(s.top-1);
}

char GetTop_ter(struct SqStack_ter &s)
{
    if(s.top!=s.base)
        return *(s.top-1);
}

void Push_val(struct SqStack &s,double e)
{
    if(s.top-s.base==s.SatckSize) cout<<"error"<<endl;
    *s.top++=e;
}


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

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

}


void Pop_ter(struct SqStack_ter &s,char &e)
{
    if(s.top==s.base) cout<<"error"<<endl;
    e=*--s.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(s_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(s_val,a);
                Push_val(s_val,double(a*10+(c-'0')));
            }
            else
            {
                //如果之前不是数字,直接push 
                Push_val(s_val,double((c-'0')));
                isNum=true;
            }
            //i++;
            c = getchar();  
        }
        else
        {
            isNum=false;
            char a;
            //Pop_ter(s_ter,a);
            a=GetTop_ter(s_ter);
            switch(getPriority(a,c))//获取栈顶元素与当前操作符的优先级 
            {
                case '>':
                    char theta; 
                    Pop_ter(s_ter,theta);   //运算符出  
                    double a_num;
                    Pop_val(s_val,a_num);  //操作数出栈
                    double b_num; 
                    Pop_val(s_val,b_num);  //操作数出栈
                    Push_val(s_val,(calculate(b_num, theta, a_num)));    
                    // c = getchar();  当读到需要计算的符号时,运算符出栈,两个操作数出栈,然后计算后将结果push栈中。 
                    //这里为何不再继续读char,不太明白 
                    break;
                case '<':
                    Push_ter(s_ter,c);
                    c = getchar();  
                    break;
                case '=':
                    char temp;
                    Pop_ter(s_ter,temp);
                    c = getchar();  
                    break;                          
            }
        }
    }   
    return calculate(*(s_val.top-2),GetTop_ter(s_ter),GetTop_val(s_val)); 
    //按此思路计算,堆栈中的top-1与top-2存放着最后两个未处理的数
    //需要做次计算才能得到最终的结果,具体原因是因为 当c读到#时,s_val中仍存放着两个未处理的数字
    //而s_ter中仍存放着最后一个操作符。 
}

int main(){
    double ans = getAnswer();   
    cout <<"答案"<<ans<< endl; 
    return 0;
}

运行
这里写图片描述
实验报告中要求计算小数,暂时没有想法,然后还想用类来写另一个版本的堆栈

猜你喜欢

转载自blog.csdn.net/hhmy77/article/details/80502100