zoukankan      html  css  js  c++  java
  • 数据结构习题集之算数表达式求值演示

    数据结构习题集实习之算数表达式求值演示

    问题描述:设计一个程序,演示用算符优先法对算数表达式求值的过程

    基本要求:以字符形式从终端输入语法正确的,不含变量的整数表达式。利用教科书表3.1给出的算符优先关系,实现对算数四则混合运算表达式的求值,并仿照教科书的例子3-1演示在求值中运算符栈、运算数栈、输入字符和主要操作的变化过程。

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include "SqStack_char.h"
    #include "SqStack_int.h"
    SqStack OPTR;
    TqStack OPND;
    char Express[50];
    int Value;
    char C='$';
    void Start();
    void Run();
    int Read();
    int IsNum(int dex);
    int PriorityCom(char A,char B);
    int Calculate(int A,char theta,int B);
    void ShowUp(int Step);
    void PrintString(int flag);
    int main()
    {
        system("color 1e");
        Start();
        Run();
        return 0;
    }
    void Start()
    {
         InitSqStack(&OPTR);//定义操作符栈,里面是存char字符
         InitTqStack(&OPND);//定义操作数栈,里面存int 整形
         PushSq(&OPTR,'#');//将一个#压入栈
         scanf("%s",Express);//输入表达式
         int n=strlen(Express);
         Express[n]='#';//将字符串结尾以#,与保持对称
         return;
    }
    void Run()
    {
        int Step=1;
        printf("步骤	OPTR栈	OPND栈	        输入字符	主要操作
    ");
        ShowUp(Step);
        PrintString(0);
        char Cur;
        int flag;
        flag=Read();
        GetSqTop(&OPTR,&Cur);
        while(C!='#'||Cur!='#')
        {
            if(flag==1)
            {
                 PushTq(&OPND,Value);//读到数值,进操作数栈
                 printf("PUSH(OPND,‘%d’ )
    ",Value);
                 Step++;
                 ShowUp(Step);
                 PrintString(0);
                 flag=Read();
            }
            else
            {
                if(PriorityCom(Cur,C)<0)//优先级大于栈顶字符,入栈
                {
                    PushSq(&OPTR,C);
                    printf("PUSH(OPTR,‘%c’)
    ",C);
                    Step++;
                    ShowUp(Step);
                    PrintString(0);
                    flag=Read();
                }
                else
                {
                    if(PriorityCom(Cur,C)==0)//优先级相等,为()的情况,出栈
                    {
                        char D;
                        PopSq(&OPTR,&D);
                        printf("POP(OPTR){消去一对括号}
    ");
                        Step++;
                        ShowUp(Step);
                        PrintString(0);
                        flag=Read();
                    }
                    else//优先级小于栈顶,进行求值操作
                    {
                        char theta;
                        int A,B;
                        PopSq(&OPTR,&theta);//操作符出栈
                        PopTq(&OPND,&B);//操作数出栈
                        PopTq(&OPND,&A);
                        PushTq(&OPND,Calculate(A,theta,B));//计算结果入栈
                        printf("operate(‘%d’,‘%c’,‘%d’)
    ",A,theta,B);
                        Step++;
                        ShowUp(Step);
                        PrintString(1);
                        flag=Read();
                    }
                }
            }//字符串结尾#与操作符栈#相遇是跳出循环
            GetSqTop(&OPTR,&Cur);//结果出栈
        }
        printf("RETURN(GETTOP(OPND))
    ");
        int Result;
        PopTq(&OPND,&Result);//打印结果
        printf("
    运算结果是:%d",Result);
        return;
    }
    int Read()//从字符串中读取操作符和操作数,其中操作数需要需要根据数个数字字符得到值
    {
        int i=0;
        while(Express[i]!='')
        {
            if(Express[i]=='$')//已经读取过的字符化为‘$'将被跳过
                i++;
            else
            {
                if(IsNum(i)==0)
                {
                    C=Express[i];
                    Express[i]='$';//将读取了的字符化为'$'
                    return  0;
                }
                else
                {
                    Value=0;
                    while(IsNum(i)==1)
                    {
                        int b=Express[i]-'0';
                        Express[i]='$';//将读取了的字符化为'$'
                        Value=Value*10+b;//数字字符串转换为整形数
                        i++;
                    }
                    return 1;
                }
            }
        }
        return -1;
    }
    
    int IsNum(int dex)//判断是否是数字字符常量
    {
        if(Express[dex]>='0'&&Express[dex]<='9')
            return 1;
        return 0;
    }
    int PriorityCom(char A,char B)//对于前后两个操作符优先级的比较,确定后续操作
    {
        if(A=='+'||A=='-')
        {
            if(B=='*'||B=='/'||B=='(')
                return -1;
            if(B=='+'||B=='-'||B==')'||B=='#')
               return  1;
        }
        if(A=='*'||A=='/')
        {
            if(B=='+'||B=='-'||B=='*'||B=='/'||B==')'||B=='#')
                return 1;
            if(B=='(')
                return -1;
        }
        if(A=='(')
        {
            if(B==')')
                return 0;
            if(B=='#')
            {
                printf("输入表达式出现语法错误
    ");
                exit(-1);
            }
            if(B=='+'||B=='-'||B=='*'||B=='/'||B=='(')
                return -1;
        }
        if(A==')')
        {
            if(B=='+'||B=='-'||B=='*'||B=='/'||B==')'||B=='#')
                return 1;
            if(B=='(')
            {
                printf("输入表达式出现语法错误
    ");
                exit(-1);
            }
        }
        if(A=='#')
        {
            if(B=='+'||B=='-'||B=='*'||B=='/'||B=='(')
                return -1;
            if(B=='#')
                return 0;
            if(B==')')
            {
                printf("输入表达式出现语法错误
    ");
                exit(-1);
            }
        }
        return 0;
    }
    int Calculate(int A,char theta,int B)
    {
        int Result=0;
        switch(theta)
        {
            case '+':
            {
                Result=A+B;
                break;
            }
            case '-':
            {
                Result=A-B;
                break;
            }
            case '*':
            {
                Result=A*B;
                break;
            }
            case '/':
            {
                Result=A/B;
                break;
            }
        }
        return Result;
    }
    /*有flag的原因是进行运算前读取的操作符既没有进栈,也没有出栈,
    但是在字符串中被抹去,当后面打印字符串时无法打印出这个字符,但后面又需要显示
    */
    void ShowUp(int Step)
    {
        printf("%d	",Step);
        TravelSq(&OPTR);
        TravelTq(&OPND);
        return;
    }
    void PrintString(int flag)//打印字符串,碰到'$’不打印
    {
        char *ptr=Express;
        while((*ptr)!='')
        {
            if((*ptr)=='$')
                ptr++;
            else
                break;
        }
        if(flag==1)
        {
            ptr--;
            *ptr=C;
        }
        printf("%16s",ptr);
        printf("	");
        return;
    }
    

    最后一个打印没有控制整齐,略微的瑕疵,但是结果是正确的。

  • 相关阅读:
    蓝桥杯--2012--奇怪的比赛(全排列)
    mysql数据库读写分离教程
    Linux中安装java JDK
    mysql数据库主从复制教程
    mysql数据库安装教程
    http报文详解
    查看磁盘I/O命令iostat详解
    linux如何查看服务器当前的并发访问量
    Another app is currently holding the yum lock; waiting for it to exit...
    linux清理缓存cache
  • 原文地址:https://www.cnblogs.com/zhichao-yan/p/13368506.html
Copyright © 2011-2022 走看看