栈的应用,中后缀表达式的转换:波兰式和逆波兰式

Posted oldfish123

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了栈的应用,中后缀表达式的转换:波兰式和逆波兰式相关的知识,希望对你有一定的参考价值。

首先是中缀表达式转后缀表达式

一下代码都调用了prior()这个函数,所以我在这里只写了一个prior函数

在粘贴的时候要注意,不要忘记prior这个函数

#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
int prior(char a){
    if(a==+||a==-){
        return 1;        
    }
    else{
        return 2;        
    }
}
以下是中缀表达式转后缀表达式 
void change(char real[],char after[]){
    char tran[100];
    int top1=-1,top2=-1;//创建过渡栈和转化后栈的栈顶
    int i=0;
    while(real[i]!=)
    {
        if(real[i]>=0&&real[i]<=9)
        {
            after[++top2]=real[i];
            ++i;
        }
            
        else if(real[i]==()
        {
            tran[++top1]=(;
            ++i;            
        }
            
        else if(real[i]==+||
                real[i]==-||
                real[i]==*||
                real[i]==/)
        {
            if(prior(real[i])>prior(tran[top1])||
            tran[top1]==(||
            top1==-1)
            {
                tran[++top1]=real[i++];    
            }
            else
                after[++top2]=tran[top1--];
        }
        else if(real[i]==))
        {
            while(tran[top1]!=()
                after[++top2]=tran[top1--];
            --top1;
            ++i;
        }
    }
    while(top1!=-1)
        after[++top2]=tran[top1--];
}

接下来式用中缀表达式模拟计算机求值的过程

//以下是中缀表达式运用栈来求表达式的值 
/*
中缀表达式就是正常的表达式
这里定义两个栈
一个为数字栈,另一个式操作符栈
1.从左往右扫描,扫到数字直接放入数字栈
2.扫到操作符就分情况讨论
    2.1当前操作符栈的top=-1
    2.2操作符的栈顶元素优先级小于扫描到的符号
    2.3当前栈顶元素为‘(‘
        以上3种情况元素均可入操作符栈
    else: 
    2.4当前元素不满足上面3个条件
        2.4.1取出数字栈上方两个数字,取出操作栈的一个元素
        放入到calculate()进行计算
        result放入number栈顶
3.若扫描到的元素是‘)‘:符号栈左右括号内的元素全部出栈 
    while(op[top]!=‘)
        取数字栈两个数字(不要搞错书顺序)
        取符号栈内元素出栈
        放入calculate()计算
        number[++top]=result;
    while结束以后: 
    操作符top--:去除(左括号
    i++:当前的右括号‘)‘已用完,i++继续扫描下一个
5.若操作栈在程序扫描结束以后仍有剩余操作符
则执行while操作,重复3内的操作,直到op的top为-1为止 
*/ 
float calculate(float a,float b,char op){
    if(op==+) return a+b;
    if(op==-) return a-b;
    if(op==*) return a*b;
    if(op==/){
        if(a==0||b==0)
            return 0;
        else
            return a/b;
    }
}
float change(char real[]){
    float num[100]; int top1=-1;
    char op[100]; int top2=-1;
    int i=0;
    while(real[i]!=)
    {
        if(real[i]>=0&&real[i]<=9)
            num[++top1]=real[i++]-0;
        else if(real[i]==()
            op[++top2]=real[i++];
        else if(real[i]==+||
                real[i]==-||
                real[i]==*||
                real[i]==/)
            {
                if(prior(real[i])>prior(op[top2])||top2==-1||op[top2]==()
                {
                    op[++top2]=real[i++];
                }
                else
                {    
                    float b=num[top1--];
                    float a=num[top1--];
                    char OP=op[top2--];
                    float flag=calculate(a,b,OP);
                    if(flag==0){
                        printf("error");
                        break;
                    }
                    num[++top1]=calculate(a,b,OP);
                }
            }
        else if(real[i]=))
        {
            while(op[top2]!=()
            {
                float b=num[top1--];
                float a=num[top1--];
                char OP=op[top2--];
                float flag=calculate(a,b,OP);
                if(flag==0)
                {
                    printf("error");
                    break;
                }
                num[++top1]=calculate(a,b,OP);
            }
            --top2;
            ++i;
        }            
    }
    while(top2!=-1){
        float b=num[top1--];
        float a=num[top1--];
        char OP=op[top2--];
        float flag=calculate(a,b,OP);
        if(flag==0){
            printf("error");
            break;
        }
        num[++top1]=calculate(a,b,OP);
    }
    return num[0];
}
int main(){
    char real[100]="3+4*5*(2+3)";
    float result=change(real);
    printf("%f
",result);
}

以下是模拟计算机求后缀表达式的过程

//以下是运用后缀表达式求值
/*
后缀表达式求值比其他简单
1.首先定义一个数字number栈 
2.把表达式从左往右扫描
3.扫描到数字就把数字放入到number栈中 
4.扫到操作符就直接取出number栈的上面两个数组进行运算
5.得到的结果放入number栈中(一定注意取数字的顺序) 
*/ 
int calculate(int a,int b,char op){
    if(op==+) return a+b;
    if(op==-) return a-b;
    if(op==*) return a*b;
    if(op==/) return a/b;
}
int change(char real[]){
    int number[10]; int top=-1; 
    int i=0;
    while(real[i]!=){
        if(real[i]>=0&&real[i]<=9)
        {
            number[++top]=real[i++]-0;//把表达式中的字符型数字改成数值型 
        }
        else
        {
            int b=number[top--];//这里一定要注意先取b,再取a 
            int a=number[top--];
            char OP=real[i];//把当前的操作符附给OP 
            number[++top]=calculate(a,b,OP);
            ++i;    
        }
    }return number[0];
}
int main(){
    char real[100]="34523+**+";
    int result=change(real);
    printf("%d
",result);
    
} 

最后,关于前缀表达的一些代码写法我就不补充了

和后缀差不多

/*
关于前缀表达式求值问题
相对于后缀表达式,扫描顺序是从右往左
所以就是i=length-1;
取数字就是按照顺序存取
先a再b
其余无变化 
*/ 
/*
关于中缀表达式转前缀表达式
不同于转后缀的是
1.从右往左扫描
2.优先级是大于(不能是等于)才能出栈
(逆波兰式是优先级大于或等于才能出栈)
其余一样 
*/ 

 

以上是关于栈的应用,中后缀表达式的转换:波兰式和逆波兰式的主要内容,如果未能解决你的问题,请参考以下文章

(C语言中)逆波兰算法(及计算器)

c语音编程,逆波兰表达式求值

逆波兰算术表达式 C语言

C++栈的应用:逆波兰式的实现

栈的应用-逆波兰式

波兰式与逆波兰式的转换和表达式求值