中缀表达式的计算C++(C语言可参考)

//中缀表达式的计算 
//将输入的算术表达式存储到字符串 S 中;
//建立并初始化操作数栈和运算符栈,并将‘#’压入运算符栈;
//建立二维数组存储算术运算符的优先关系;
//建立并初始化一个临时栈T用来处理多位数或小数;
// 依次(循环)读.. ch 是操作数,将其入临时栈;
/*当读入的字符 ch 是运算符:
将临时栈中的数据转化为整数或小数(这需要编写个函数),
并将转化后的数据入操作数栈,清空临时栈;
// 根据运算符栈的栈顶元素和 ch 的优先权比较结果,做不同的处理:
a)若是小于,则 ch 压入运算符栈,读入下一个字符;
//b)若是大于,则弹出运算符栈顶的运算符,从操作数栈弹出两个数,进行相
//应运算,将结果压入操作数栈;
c)若是等于,则运算符栈顶元素是‘(’且 ch 是‘)’,这时弹出运算符栈顶的
‘(’,相当于去括号,然后读入下一个字符;
d)当读入的字符 ch 是‘#’,且运算符栈顶元素也是‘#’时,
算法结束。*/


输入示例:

/*
2+3+5*6-(8+2)-6/2
>><<<>
>><<<>
>>>><>
>>>><>
<<<<<=
*/

//下面代码中注释部分是写作是验证用的,读者可以直接删除或者忽视,在代码中不起任何作用!


#include<iostream>
using namespace std;
#define MAXSIZE 20
#define N 10
//运算符栈 
typedef struct 
{
    char *base;
    char *top;
    int size;
 }stack1;
//操作数栈
typedef struct
{
    int *base;
    int *top;
    int size;
 }stack2;
//为什么没有必要建一个临时栈
//运算符栈的初始化 
void init1(stack1 &S)
{
    S.base=new char[MAXSIZE];
    S.top=S.base;
    S.size=MAXSIZE;
//    *S.top++='#';//讨论*S.top++=和S.top++ 
}
//操作数栈的初始化 
void init2(stack2 &S)
{
    S.base=new int[MAXSIZE];
    S.top=S.base;
    S.size=MAXSIZE;
 } 
//运算符入栈 
void push1(stack1 &S,char e)
{
    if(S.top-S.base==S.size)
        exit(0);
    *S.top++=e;
 }
//操作数入栈 
void push2(stack2 &S,char e)
{
    if(S.top-S.base==S.size)
        exit(0);
    *S.top++=e-48;
 } 
//运算符出栈
void pop1(stack1 &S,char &e)
{
    if(S.base==S.top)
        exit(0);
    e=*--S.top;
 } 
//操作数出栈
void pop2(stack2 &S,int &e)
{
    if(S.base==S.top)
        exit(0);
    e=*--S.top;
 } 
int verify(char ch)
{
    //cout<<ch<<endl;
    if(ch=='+')
        return 0;
    else if(ch=='-')
        return 1;
    else if(ch=='*')
        return 2;
    else if(ch=='/')
        return 3;
    else if(ch=='(')
        return 4;
    else if(ch==')')
        return 5;
    else
    {
        //cout<<ch<<endl;
        //cout<<"此时运算符栈为空!"<<endl;
        return 100;
    }
        
}
//判断并计算 
int judge(int a,char e,int b)
{
    //cout<<e<<endl;
    if(e=='+')
        return a+b;
    else if(e=='-')
        return a-b;
    else if(e=='*')
        return a*b;
    else if(e=='/')
        return a/b;
    else
    {
        cout<<"error!"<<endl;
        return 100;
    }
        
}
void precede(stack1 &S1,stack2 &S2,char ch,char p[][N])
{ 
    //cout<<"11111111111"<<endl;
    char e; 
    int a,b,c,flag=1;
    if(S1.top==S1.base)
    {
        push1(S1,ch);
        flag=0;
        }
    
    //cout<<p[i][j]<<" "; 
    //p[i][j];
    while(flag!=0)
    {
        int i=verify(*(S1.top-1));
        int j=verify(ch);
        //cout<<"333"<<endl;
        if(S1.top==S1.base)
        {
        //    cout<<"8888"<<endl;
            push1(S1,ch);
            flag=0;
        }
        else
        {
            if(p[i][j]=='>')//栈顶>ch  
            {
        //        cout<<"sssssss"<<endl;
                pop1(S1,e);//运算符出栈 
                pop2(S2,a);
                pop2(S2,b);
        //        cout<<"a="<<a<<" b="<<b<<" e="<<e<<endl;
        //        if(e=='(')
        //        cout<<"i="<<i<<" j="<<j<<" ch="<<ch<<endl;
                c=judge(b,e,a);//计算
        //        cout<<c<<endl;
                c=c+48;
                push2(S2,c);//入栈 
        //        cout<<"S2.top="<<*(S2.top-1)<<endl;
        //    cout<<"okok!"<<endl; 
            }
            else if(p[i][j]=='<')
            {
        //        cout<<"eeeeeee"<<endl;
                push1(S1,ch);//入栈:  top<ch 
                flag=0;
        //    cout<<"dddd"<<endl;
            }    
            else if(p[i][j]=='=')
            {
        //        cout<<"[[[[[[[[]]]]]]]]"<<endl;
                pop1(S1,e); //出栈
                flag=0;
        //    cout<<"fffffffff"<<endl;
            }     
            else
                cout<<"predede error!"<<endl;
    }
        
//    cout<<*(S2.top-1)<<endl;
//    cout<<"S1.top="<<*(S1.top-1)<<endl;
    }
    
}
    
void final(stack1 &S1,stack2 &S2)
{
    int a,b,c;
    char e;
    pop1(S1,e);
    pop2(S2,b);
    pop2(S2,a);
//    cout<<a<<e<<b<<endl;
    c=judge(a,e,b);
//    cout<<c<<endl;
    c=c+48;
//    cout<<c<<endl;
    push2(S2,c); 
}
int main()
{
    stack1 S1;
    stack2 S2;
    init1(S1);
    init2(S2);
    string S;
    cin>>S;
    char p[N][N];//存储优先级关系 
    for(int i=0;i<5;i++)
        for(int j=0;j<6;j++)
        {
            cin>>p[i][j];
         } 
    for(int i=0;S[i]!='\0';i++)
    {
    //    cout<<"4444444"<<endl;
        if(S[i]>='0'&&S[i]<='9')//是数字
        {
            push2(S2,S[i]);//入操作数栈 
    //        cout<<"22222222"<<endl;
        }
             
        else//是字符 
        {
            //如果top<ch,ch入栈;如果top>ch,弹出top,弹出两个操作数,进行计算,结果压入操作数栈;
            //如果=,弹出栈顶 
            //cout<<S1.top<<endl;
        //    cout<<"jjjj"<<endl;
            precede(S1,S2,S[i],p);//存在死循环 
        //    cout<<"????"<<endl;
        }
     } 
    while(S1.base!=S1.top)//栈不空
    {
        final(S1,S2);
     } 
    //cout<<"finally!"<<endl;
    cout<<*(S2.top-1);
}

 

运行说明:

输入的时候,先输入一个式子,

然后,输入下面的符号(直接复制粘贴即可):

 >><<<>
>><<<>
>>>><>
>>>><>
<<<<<=

输入这些玩意的主要原因呢是因为——代码中考虑运算符优先级的时候,将不同运算符之间的优先级关系存在了一个二维数组里!

咱们输入的这堆东西,就是二维数组存储的内容!

  • 9
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

try again!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值