zoukankan      html  css  js  c++  java
  • 计算表达式的值--顺序栈(数据结构第二次实验)

    实验题目:栈的应用-算术表达式求值                      

    实验环境:    Visual C++ 6.0                    

    实验目的 :

    1 .掌握栈的定义及实现;

    2 .掌握利用栈求解算术表达式的方法。

    实验内容:

    通过修改完善教材中的算法3.4,利用栈来实现算术表达式求值的算法。对算法3.4中调用的几个函数要给出其实现过程:

    (1) 函数In(c):判断c是否为运算符;

    (2) 函数Precede(t1,t2):判断运算符t1和t2的优先级;

    (3) 函数Operate(a,theta,b):对a和b进行二元运算theta。

    程序运行时,输入合法的算术表达式(中间值及最终结果要在0~9之间,可以包括加减乘除和括号),便可输出相应的计算结果。如下图:

    实验提示 : (仅供参考,每个函数的具体实现可以有多种方法,希望有创新)

    1. 将栈的定义和实现单独保存在头文件“stack.h”中,然后在表达式求值的源程序中包含此头文件(即#include“stack.h”)。

    2. 表达式求值源程序的具体实现

    (1) 主函数如下:

    void main()

     {

       Printf(“ 请输入算术表达式,并以#结束. ”);

      Printf(“the result of expression is:%d ”,EvaluateExpression());

     }

    (2) 函数EvaluateExpression的实现见算法3.22

    (3) 函数In(c)的实现可以采用以下方式:

    Status In(SElemType c)// 应在前面有定义typedef char SElemType;

     { // 判断c是否为运算符

       switch(c)

       {

         case'+':return TRUE;

         ……// 补充完整

    default:return FALSE;

       }

     }

    (4) 函数Precede(t1,t2)的实现可以采用以下形式:

    SElemType Precede(SElemType t1,SElemType t2)

     { // 根据教材表3.1,判断两个运算符的优先关系

       SElemType f;

       switch(t2)

       {

         case '+':

         case '-':if(t1=='('||t1=='#')

                    f='<';

                  else

                    f='>';

                  break;

    ……// 补充完整

    }

       return f;

    }

    (5) 函数Operate(a,theta,b)的实现可以采用以下方式:

    SElemType Operate(SElemType a,SElemType theta,SElemType b)

     {

       SElemType c;

       a=a-48;

       b=b-48;

       switch(theta)

       {

         case'+':c=a+b+48;

                 break;

    ……// 补充完整

       }

       return c;

     }

     

     

    选做内容: 进一步改进,使表达式的中间值及最终结果不局限于0~9之间的个位数。(如果完成要在实验报告中注明),如下图:

    实验要求 :

    (1) 程序要添加适当的注释,程序的书写要采用 缩进格式 。

    (2) 程序要具在一定的 健壮性,即当输入数据非法时, 程序也能适当地做出反应。

    (3) 程序要做到 界面友好,在程序运行时用户可以根据相应的提示信息进行操作。

    (4) 根据实验报告模板详细书写实验报告,在实验报告中给出 表达式求值算法的流程图 。

    (5) 上传源程序到Sakai网络教学平台。顺序表的源程序保存为 calculator.cpp。

    #include<stdio.h> 
    #include<malloc.h>
    #include<stdlib.h>
    #include<string.h>
    #define OVERFLOW -2
    #define MAXSIZE 100
    #define OK 1 
    #define ERROR 0
    #define TRUE 1
    #define FALSE 0
    #include<iostream>
    using namespace std;
    
    typedef int Status;
    typedef char SElemType;
    
    //--------顺序栈的存储结构------
    typedef struct 
    {
        SElemType *base;    //栈底指针 
        SElemType *top;    //栈顶指针 
        int stacksize;     //占可用的最大容量 
    }SqStack; 
    
    
    Status InitStack (SqStack &S)
    {//构造一个空栈 
        S.base=new SElemType[MAXSIZE];   //为顺序栈动态分配一个最大容量为MAXSIZE的数组空间 
        if (!S.base) exit(OVERFLOW);    //动态分配失败
        S.top=S.base;     //top初始为base,空栈 
        S.stacksize=MAXSIZE;   //stacksize置为栈的最大容量MAXSIZE 
        return OK;
        
    }
    
    Status Push(SqStack &S,SElemType e) 
    {//插入元素e为新的栈顶元素
        if(S.top-S.base==S.stacksize)   return ERROR;   //栈满 
        *S.top++=e;    //元素e压入栈顶,栈顶指针加1 
        return OK;
        
    }
    
    Status Pop(SqStack &S,SElemType &e)
    {//删除s的栈顶元素,用e返回其    
        if (S.top==S.base)  return ERROR;  //栈顶 
        e=*--S.top;   // 栈顶指针减1,将栈顶元素为e 
        return OK;
        
    } 
    
    SElemType GetTop(SqStack S) 
    {//返回S的栈顶元素,不修改栈顶指针、
        if(S.top!=S.base)   //栈非空
            return *(S.top-1);   //返回栈顶元素的值,栈顶指针不变 
        
    }
    
    
    Status In(SElemType c)
    {
        switch(c)          //判断读入的字符是哪一种运算符, 
        {
            case '+':
                return TRUE;
                break; 
            case '-':
                return TRUE;
                break;
            case '*':
                return TRUE;
                break;
            case '/':
                return TRUE;
                break;
            case '(':
                return TRUE;
                break;
            case ')':
                return TRUE;
                break;
            case '#':
                return TRUE;
                break;
            default:
                return FALSE;
                
        }
    }
    
    SElemType Precede(SElemType t1,SElemType t2)
    {
        SElemType f;       
        switch(t2)     //判断运算符栈的栈顶元素和读入的运算符之间谁的优先级更高,并返回结果 
        {
            case '+':
                if (t1=='('||t1=='#')
                    f='<';
                else
                    f='>';
                break;
                
            case '-':
                if (t1=='('||t1=='#')
                    f='<';
                else
                    f='>';
                break;
                
            case '*':
                if (t1=='+'||t1=='-'||t1=='('||t1=='#')
                    f='<';
                else
                    f='>';
                break;
                
            case '/':
                if (t1=='+'||t1=='-'||t1=='('||t1=='#')
                    f='<';
                else
                    f='>';
                break;
                    
            case '(':
                if (t1=='+'||t1=='-'||t1=='('||t1=='#'||t1=='*'||t1=='/')
                    f='<';
                break;
                
            case ')':
                if (t1=='+'||t1=='-'||t1=='*'||t1=='/'||t1==')')
                    f='>';
                else if (t1=='(')
                    f='=';
                break;
                
            case '#':
                if (t1=='#')
                    f='=';
                else
                    f='>';
                break;    
            default:
                cout<<"输入超出范围。。。";
            
        }
        return f;
    }
    
    
    SElemType Operate(SElemType a,SElemType theta,SElemType b)
    {    
        SElemType c;
        a=a-'0';      //因为a,b均为字符型,所以转化成int型 
        b=b-'0';
        switch(theta)
        {
            case '+':
                c=a+b+'0';break;        //再将计算的结果转化为字符型 
            case '-':
                c=a-b+'0';break;
            case '*':
                c=a*b+'0';break;
            case '/':
                c=a/b+'0';break;        
        }
        return c;   //返回计算结果 
    }
    
    char EvaluateExpression()
    {//算数表达式求值的算符优先算法,设OPTR和 OPND分别为运算符栈和操作数栈
        SqStack OPND,OPTR;
        char ch,theta,a,b,c,x,w;
        InitStack(OPND);  //初始化OPND栈 
        InitStack(OPTR);  //初始化OPTR栈 
        Push(OPTR,'#');   //将表达式起始符“#”OPTR栈 
        cin>>ch;
        while (ch!='#'||GetTop(OPTR)!='#')    //表达式没有扫描完毕或者OPTR的栈顶元素不为“#” 
        {
            if (!In(ch))     //判断ch是不是运算符,不是则压入OPND栈 
                {
                    Push(OPND,ch);
                    cin>>ch;
                }
            else
                switch(Precede(GetTop(OPTR),ch))   // 比较OPTR的栈顶元素和ch的优先级 
                {
                    case '<':
                        Push(OPTR,ch);        //当前字符ch压入OPTR栈 ,读入下一个字符ch 
                        cin>>ch;
                        break;
                    case '>':
                        Pop(OPTR,theta);    //弹出OPTR栈顶的运算符 
                        Pop(OPND,b);        //弹出OPND栈顶的运算数, 
                        Pop(OPND,a);        //弹出OPND栈顶的运算数,
                        Push(OPND,Operate(a,theta,b));     //将运算结果压入OPND栈 
                        break;
                    case '=':               //OPTR的栈顶元素是“(”且ch是“)”
                        Pop(OPTR,x);        //弹出OPTR栈顶的"(",
                        cin>>ch;            //读入下一个字符ch 
                        break;
                    
                }
        }
        return GetTop(OPND);              //OPND栈顶元素即为表达式求值结果 
        
    }
    int main()
    {
        char w;
        cout<<"请输入算数表达式,并以#结束
    ";
        w=EvaluateExpression();    //将运算结果赋值给w 
        w=w-48;         //将字符转换成数字 
        printf("The result of expression is %d
    ",w); 
                       
    }
  • 相关阅读:
    小程序的媒体组件
    微信小程序开发系列之Hello World
    centos 6 mysql 5.6 源码安装
    php 源码安装
    centos7 源码安装nginx
    CentOS 7.2部署MariaDB Galera Cluster(10.1.21-MariaDB) 3主集群环境
    MySQL读写分离
    MySQL主从复制(Master-Slave)实践
    lvs+keepalived+nginx负载均衡搭建
    Kubernetes在CentOS7下二进制文件方式安装、离线安装
  • 原文地址:https://www.cnblogs.com/xisheng/p/7810708.html
Copyright © 2011-2022 走看看