C++表达式求值


C++表达式求值

操作符符号栈优先级

操作符ch#(*,/,%+,-)
isp(栈内)01536
icp(栈外)06421
#include <iostream>
#include <assert.h>
#include<string.h>
#include<stdio.h>
#include<stdlib.h>
using namespace std;
class SeqStack                           //顺序栈类定义
{
private:
    char *elements;		 //栈元素存放数组
    int top;				             //栈顶指针
    int maxSize;               		//栈最大容量
    void overflowProcess();	            //栈的溢出处理
public:
    SeqStack(int sz =50);		                   //构造函数
    ~SeqStack()
    {
        delete []elements;    //析构函数
    }
    void Push(char &x);	          		        //进栈
    int Pop(char& x);		                  //出栈
    int getTop(char& x); 	      //取栈顶内容
    int IsEmpty() const
    {
        return top == -1;
    }
    int IsFull() const
    {
        return top == maxSize-1;
    }
    int getSize() const
    {
        return top+1;
    }
    void MakeEmpty()
    {
        top=-1;
    }
    void output();
};
SeqStack:: SeqStack(int sz)
{
    elements=new char[sz];
    assert(elements!=NULL);
    top=-1;
    maxSize=sz;
}
void SeqStack::overflowProcess()
{
//私有函数:当栈满则执行扩充栈存储空间处理
    char *newArray = new char [2*maxSize];				//创建更大的存储数组
    for (int i = 0; i <= top; i++)
        newArray[i] = elements[i];
    maxSize += maxSize;
    delete [ ]elements;
    elements = newArray;  	//改变elements指针
};
void SeqStack::Push(char & x)
{
//若栈满,则溢出处理,将元素x插入该栈栈顶
    if (IsFull())
        overflowProcess(   );           //栈满
    elements[++top]   = x;            //栈顶指针先加1, 再进栈
};
int SeqStack::Pop(char & x)
{
//若栈不空,函数退出栈顶元素并将栈顶元素的值赋给x,
//返回1,否则返回0
    if (IsEmpty())
        return 0;
    x = elements[top--]  ;       //先取元素,栈顶指针退1
    return 1;		                        //退栈成功
};
int SeqStack::getTop(char& x)
{
//若栈不空则x为该栈栈顶元素
    if (IsEmpty())
        return 0;
    x = elements[top];
    return 1;
};
void SeqStack::output(   )
{
    cout<<"元素个数为:"<<top+1<<endl;
    for (int i=0; i<=top; i++)
        cout <<i+1<<":"<<elements[i] <<endl;
};

//整数栈
class SeqStackInt                           //顺序栈类定义
{
private:
    int *elements;		 //栈元素存放数组
    int top;				             //栈顶指针
    int maxSize;               		//栈最大容量
    void overflowProcess();	            //栈的溢出处理
public:
    SeqStackInt(int sz =50);		                   //构造函数
    ~SeqStackInt()
    {
        delete []elements;    //析构函数
    }
    void Push(int &x);	          		        //进栈
    int Pop(int& x);		                  //出栈
    int getTop(int& x); 	      //取栈顶内容
    int IsEmpty() const
    {
        return top == -1;
    }
    int IsFull() const
    {
        return top == maxSize-1;
    }
    int getSize() const
    {
        return top+1;
    }
    void MakeEmpty()
    {
        top=-1;
    }
    void output();
};
SeqStackInt:: SeqStackInt(int sz)
{
    elements=new int[sz];
    assert(elements!=NULL);
    top=-1;
    maxSize=sz;
}
void SeqStackInt::overflowProcess()
{
//私有函数:当栈满则执行扩充栈存储空间处理
    int *newArray = new int [2*maxSize];				//创建更大的存储数组
    for (int i = 0; i <= top; i++)
        newArray[i] = elements[i];
    maxSize += maxSize;
    delete [ ]elements;
    elements = newArray;  	//改变elements指针
};
void SeqStackInt::Push(int & x)
{
//若栈满,则溢出处理,将元素x插入该栈栈顶
    if (IsFull())
        overflowProcess(   );           //栈满
    elements[++top]   = x;            //栈顶指针先加1, 再进栈
};
int SeqStackInt::Pop(int & x)
{
//若栈不空,函数退出栈顶元素并将栈顶元素的值赋给x,
//返回1,否则返回0
    if (IsEmpty())
        return 0;
    x = elements[top--]  ;       //先取元素,栈顶指针退1
    return 1;		                        //退栈成功
};
int SeqStackInt::getTop(int& x)
{
//若栈不空则x为该栈栈顶元素
    if (IsEmpty())
        return 0;
    x = elements[top];
    return 1;
};
void SeqStackInt::output(   )
{
    cout<<"元素个数为:"<<top+1<<endl;
    for (int i=0; i<=top; i++)
        cout <<i+1<<":"<<elements[i] <<endl;
};

//浮点数栈
class SeqStackDouble                           //顺序栈类定义
{
private:
    double *elements;		 //栈元素存放数组
    int top;				             //栈顶指针
    int maxSize;               		//栈最大容量
    void overflowProcess();	            //栈的溢出处理
public:
    SeqStackDouble(int sz =50);		                   //构造函数
    ~SeqStackDouble()
    {
        delete []elements;    //析构函数
    }
    void Push(double &x);	          		        //进栈
    int Pop(double& x);		                  //出栈
    int getTop(double& x); 	      //取栈顶内容
    int IsEmpty() const
    {
        return top == -1;
    }
    int IsFull() const
    {
        return top == maxSize-1;
    }
    int getSize() const
    {
        return top+1;
    }
    void MakeEmpty()
    {
        top=-1;
    }
    void output();
};
SeqStackDouble:: SeqStackDouble(int sz)
{
    elements=new double[sz];
    assert(elements!=NULL);
    top=-1;
    maxSize=sz;
}
void SeqStackDouble::overflowProcess()
{
//私有函数:当栈满则执行扩充栈存储空间处理
    double *newArray = new double [2*maxSize];				//创建更大的存储数组
    for (int i = 0; i <= top; i++)
        newArray[i] = elements[i];
    maxSize += maxSize;
    delete [ ]elements;
    elements = newArray;  	//改变elements指针
};
void SeqStackDouble::Push(double & x)
{
//若栈满,则溢出处理,将元素x插入该栈栈顶
    if (IsFull())
        overflowProcess(   );           //栈满
    elements[++top]   = x;            //栈顶指针先加1, 再进栈
};
int SeqStackDouble::Pop(double & x)
{
//若栈不空,函数退出栈顶元素并将栈顶元素的值赋给x,
//返回1,否则返回0
    if (IsEmpty())
        return 0;
    x = elements[top--]  ;       //先取元素,栈顶指针退1
    return 1;		                        //退栈成功
};
int SeqStackDouble::getTop(double& x)
{
//若栈不空则x为该栈栈顶元素
    if (IsEmpty())
        return 0;
    x = elements[top];
    return 1;
};
void SeqStackDouble::output(   )
{
    cout<<"元素个数为:"<<top+1<<endl;
    for (int i=0; i<=top; i++)
        cout <<i+1<<":"<<elements[i] <<endl;
};



int isp(char x)
{
    switch(x)
    {
    case '#':return 0;case '(':return 1;case '*':return 5;
    case '/':return 5;case '%':return 5;case '+':return 3;
    case '-':return 3;case ')':return 6;
    }
}
int icp(char x)
{
    switch(x)
    {
    case '#':return 0;case '(':return 6;case '*':return 4;
    case '/':return 4;case '%':return 4;case '+':return 2;
    case '-':return 2;case ')':return 1;
    }
}

//中缀转后缀
int transfer(char (&Infix)[100],char (&Postfix)[100][100],int &Inlast,int &polast)//Infix,postfix指针
{
    SeqStack S;
    int flag=0;//0表示整数,1表示浮点数
    char ch='#',ch1,op;
    S.Push(ch);
    ch=Infix[Inlast++];
    while(!S.IsEmpty()&&ch!='#')
    {
        if (isdigit(ch)||ch=='.')
        {
            if(ch=='.')
                flag=1;
            int len=strlen(Postfix[polast]);
            Postfix[polast][len]=ch;
            ch=Infix[Inlast++];
        }
        else
        {
            S.getTop(ch1);
            if (isp(ch1)<icp(ch))
            {
                polast++;
                S.Push(ch);
                ch=Infix[Inlast++];
            }
            else if (isp(ch1)>icp(ch))
            {
                S.Pop(op);
                polast++;
                if(op!='#')
                    Postfix[polast][0]=op;
            }
            else
            {
                S.Pop(op);
                if(op=='(')
                    ch=Infix[Inlast++];
            }
        }
    }
    return flag;
//    //验证
//    for(int k=0;k<polast;k++)
//        printf("%s\n",Postfix[k]);
}

template<typename T>
T calculate(T leftnum,T rightnum,char x)
{
    switch(x)
    {
    case '+':
        return leftnum+rightnum;
    case '-':
        return leftnum-rightnum;
    case '*':
        return leftnum*rightnum;
    case '/':
        return leftnum/rightnum;
    case '%':
        return (int)leftnum%(int)rightnum;
    }
}


//求整数解
int SolutionInt(char (&PoString)[100][100],int &Inlast,int &polast)
{
    int sum=0,Result;
    SeqStackInt SI;
    for(int k=0;k<polast;k++)//循环后缀表达式数组并将它们入栈计算
    {
        int len=strlen(PoString[k]);
        if(!len)
            continue;
        else if(isdigit(PoString[k][0]))
        {
            sum=atoi(PoString[k]);
            SI.Push(sum);
            sum=0;
        }
        else
        {
            int leftnum,rightnum;
            SI.Pop(rightnum);
            SI.Pop(leftnum);
            Result=calculate(leftnum,rightnum,PoString[k][0]);
            SI.Push(Result);
        }
    }
    SI.getTop(Result);
    return Result;
}

//求浮点数

double SolutionDouble(char (&PoString)[100][100],int &Inlast,int &polast)
{
    double sum=0,Result;
    SeqStackDouble SD;
    for(int k=0;k<polast;k++)//循环后缀表达式数组并将它们入栈计算
    {
        int len=strlen(PoString[k]);
        if(!len)
            continue;
        else if(isdigit(PoString[k][0]))
        {
            sum=atof(PoString[k]);
            SD.Push(sum);
            sum=0;
        }
        else
        {
            double leftnum,rightnum;
            SD.Pop(rightnum);
            SD.Pop(leftnum);
            Result=calculate(leftnum,rightnum,PoString[k][0]);
            SD.Push(Result);
        }
    }
    SD.getTop(Result);
    return Result;
}

//中缀表达式,其中若ff返回0,则表示整形,若ff返回1,则表示浮点型
double Process(char (&InString)[100],int &ff)
{
    char PoString[100][100];//后缀表达式
    int Inlast,polast,flag;
    Inlast=0;
    polast=0;
    flag=transfer(InString,PoString,Inlast,polast);
    if(!flag)
    {
        int Result=SolutionInt(PoString,Inlast,polast);
        ff=0;
        return Result;
    }
    else
    {
        double Result=SolutionDouble(PoString,Inlast,polast);
        ff=1;
        return Result;
    }
}

int main()
{
    char InString[100];//中缀表达式
    scanf("%s",InString);
    int a;
    double b;
    b=Process(InString,a);
    //printf("%d\n",a);
    if(a)
        printf("%lf\n",b);
    else
        printf("%d\n",(int)b);
    return 0;
}

运行结果

浮点数运算
在这里插入图片描述
整数运算
在这里插入图片描述

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值