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


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

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

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

    #include<stdio.h>
    #include<stdlib.h>
    #include<stdbool.h>

    //以下都调用了prior函数 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.优先级是大于(不能是等于)才能出栈
    (逆波兰式是优先级大于或等于才能出栈)
    其余一样 
    */ 
  • 相关阅读:
    006_02SQLite_OpenHelper
    006_01SQLite_demo
    005_01XML_Serilizer
    004_05PullParser
    004_04SharedPreferences
    004_02文件读写模式
    004_01获取SD容量
    003_01电话拨号器
    maven项目中的pom.xml
    ORACLE提示表名无效
  • 原文地址:https://www.cnblogs.com/oldfish123/p/12896021.html
Copyright © 2020-2023  润新知