0
点赞
收藏
分享

微信扫一扫

栈的应用之表达式求值

梦幻之云 2022-03-25 阅读 75
c++

目录

中缀表达式转换成后缀表达式

输入的处理

我个人认为表达式处理的核心思路和难点就在于,中缀表达式转换成后缀表达式,符号优先级和输入的处理。

中缀表达式转换成后缀表达式

for(;k<i;k++)
    {
        if(c[k]>='0'&&c[k]<='9')
        change(c,&k,i,S1);
        else
    {
        switch(c[k])
        {
        case '(':
            push(S2,c[k]);
            break;
        case ')':
            if(S2->date[S2->top]=='(')
                pop(S2,&d);
            else
                like(S1,S2);
            break;
        case '+':
        case '-':
            if(likestackempty(S2)||S2->date[S2->top]=='(')
                ;
            else
            {
                while(S2->date[S2->top]=='*'||S2->date[S2->top]=='/'||S2->date[S2->top]==')'||S2->date[S2->top]=='-'||S2->date[S2->top]=='+')
                like(S1,S2);
            }
            push(S2,c[k]);
            break;
        case '*':
        case '/':
            if(S2->date[S2->top]!=')'&&S2->date[S2->top]!='*'&&S2->date[S2->top]!='/')
            ;
            else
            {
                while(S2->date[S2->top]==')'||S2->date[S2->top]=='*'||S2->date[S2->top]=='/')
                like(S1,S2);
            }
            push(S2,c[k]);
            break;
        }
    }
   }

转换的过程中要满足:符号优先级比操作符栈顶符号高的就进行入栈操作,低的就将数字栈弹栈两次,操作符栈弹出一次。 之后要注意假设a是数字栈栈顶,b是数字栈次栈顶,则要将b op a 的结果压入数字栈。

下图是上述操作的代码

void like(likestack1 *S1,likestack2 *S2)
{
    double b,a;
    char e;
    pop(S1,&a);
    pop(S1,&b);
    pop(S2,&e);
    switch(e)
    {
    case '*':
        push(S1,b*a);
        break;
    case '/':
        push(S1,b/a);
        break;
    case '+':
        push(S1,b+a);
        break;
    case '-':
        push(S1,b-a);
        break;
    }
}

输入的处理

输入时要注意多位数字和小数的处理,一种思路是用string类去处理,一种是用字符数组自己写个处理函数,这边是第二种(qaq)。

void change (char c[],int *k,int i,likestack1 *S1)
{
    int a;
    double b=0;
    a=*k;
    if(c[a+1]=='.')
    {
        b=c[a]-48;
        a=a+2;
        while(a<i)
        {
             b+=(c[a]-48)*pow(10,*k-a+1);
             a++;
             if(c[a]>'9'||c[a]<'0')
                break;
        }
        push(S1,b);
        *k=a-1;
    }
    else if(c[a+1]>='0'&&c[a+1]<='9')
    {
       a++;
       while(c[a+1]<='9'&&c[a+1]>='0')
       {
           a++;
       }
       for(;*k<=a;*k=*k+1)//??
       {
           b+=(c[*k]-48)*pow(10,a-*k);
       }
       push(S1,b);
       *k=*k-1;
    }
    else
    push(S1,c[a]-48);
}

具体思路就这样了。。。。。。第一次写博客,初心想的是,一方面可以当作复习资料,另一方面也可以让其他人参考参考。写的不好的地方请多担待,下次见(下附完整代码)。

#include <iostream>
#define MAXSIZE 100
#include <cstring>
#include <cmath>
#include <iomanip>
using namespace std;
struct likestack1
{
    int top;
    double date[MAXSIZE];
};
struct likestack2
{
    int top;
    char date[MAXSIZE];
};
template <class T1,class T2>
bool push(T1 *S,T2 e)
{
    if(S->top==MAXSIZE-1)
    return false;
    S->top++;
    S->date[S->top]=e;
    return true ;
}
template <class T1,class T2>
bool pop(T1 *S,T2 *e)
{
    if(S->top==-1)
    return false;
    *e=S->date[S->top];
    S->top--;
    return true;
}
template <class T1,class T2>
bool gettop(T1 *S,T2 *e)
{
    if(S->top==-1)
    return false;
    *e=S->date[S->top];
     return true;
}
template <class T>
bool likestackempty(T *S)
{
    if(S->top==-1)

    return true;
    else
    return false;
}
void like(likestack1 *S1,likestack2 *S2)
{
    double b,a;
    char e;
    pop(S1,&a);
    pop(S1,&b);
    pop(S2,&e);
    switch(e)
    {
    case '*':
        push(S1,b*a);
        break;
    case '/':
        push(S1,b/a);
        break;
    case '+':
        push(S1,b+a);
        break;
    case '-':
        push(S1,b-a);
        break;
    }
}

void change (char c[],int *k,int i,likestack1 *S1)
{
    int a;
    double b=0;
    a=*k;
    if(c[a+1]=='.')
    {
        b=c[a]-48;
        a=a+2;
        while(a<i)
        {
             b+=(c[a]-48)*pow(10,*k-a+1);
             a++;
             if(c[a]>'9'||c[a]<'0')
                break;
        }
        push(S1,b);
        *k=a-1;
    }
    else if(c[a+1]>='0'&&c[a+1]<='9')
    {
       a++;
       while(c[a+1]<='9'&&c[a+1]>='0')
       {
           a++;
       }
       for(;*k<=a;*k=*k+1)//??
       {
           b+=(c[*k]-48)*pow(10,a-*k);
       }
       push(S1,b);
       *k=*k-1;
    }
    else
    push(S1,c[a]-48);
}
int main()
{
    char c[100],d;
    int i=0,k=0;
    likestack1 *S1=new likestack1;
    likestack2 *S2=new likestack2;
    S1->top=-1;
    S2->top=-1;
    cin>>c;
    i=strlen(c)-1;
    for(;k<i;k++)
    {
        if(c[k]>='0'&&c[k]<='9')
        change(c,&k,i,S1);
        else
    {
        switch(c[k])
        {
        case '(':
            push(S2,c[k]);
            break;
        case ')':
            if(S2->date[S2->top]=='(')
                pop(S2,&d);
            else
                like(S1,S2);
            break;
        case '+':
        case '-':
            if(likestackempty(S2)||S2->date[S2->top]=='(')
                ;
            else
            {
                while(S2->date[S2->top]=='*'||S2->date[S2->top]=='/'||S2->date[S2->top]==')'||S2->date[S2->top]=='-'||S2->date[S2->top]=='+')
                like(S1,S2);
            }
            push(S2,c[k]);
            break;
        case '*':
        case '/':
            if(S2->date[S2->top]!=')'&&S2->date[S2->top]!='*'&&S2->date[S2->top]!='/')
            ;
            else
            {
                while(S2->date[S2->top]==')'||S2->date[S2->top]=='*'||S2->date[S2->top]=='/')
                like(S1,S2);
            }
            push(S2,c[k]);
            break;
        }
    }
   }
    while(1)
    {
        if(S2->top==-1)
            break;
        like(S1,S2);
    }
   cout<<fixed<<setprecision(2)<<S1->date[S1->top];
     return 0;
}
举报

相关推荐

0 条评论