数据结构实验----栈

一.实验目的

1.理解栈的结构特点和基本操作特性;

2.掌握利用栈实现表达式求值算法。

二.实验内容

输入一个算术表达式(以“=”结束),求其值。要求表达式以“=”结束,操作数为多位实数,对错误表达式要进行检测。

1.设置两个栈:optr算符栈和opnd操作数栈。初始置opnd为空栈;起始符“=”为optr的栈底元素;

2.自左向右扫描表达式中的每个字符c:

1)若c为操作数,则进opnd栈;

2)若c为算符,则让optr栈的栈顶元素与c比较优先级:

a.若栈顶算符优先级低于刚读入的运算符c,则让刚读入的运算符c进optr栈。

b.若栈顶算符优先级高于刚读入的运算符c,则将栈顶算符退栈,送入q;同时将操作数栈opnd退栈两次,得到两个操作数b、a,对a、b进行aqb运算后,将运算结果作为中间结果推入opnd栈。

c.若栈顶运算符的优先级与刚读入的运算符c相同,说明左右括号相遇,只需将栈顶运算符(左括号)退栈即可。

3.直到扫描到c为定界符,即optr栈的栈顶元素和当前读入的字符均为“=”,则整个表达式求值完毕。

三.代码

#include <iostream>
#include <algorithm>
#include <cmath>

using namespace std;

#define MAXSIZE 100 
#define ERROR -1
typedef double DataType;  // 将 DataType 改为 double 以处理浮点数
typedef struct{
    DataType data[MAXSIZE];
    int top;
}SqStack;

// 构建一个空栈
int InitStack(SqStack &S){
    S.top = -1;
    return true;
}

// 判断栈是否为空
int StackEmpty(SqStack S){
    return (S.top == -1? true:false);
}

// 判断栈是否满了
int StackFull(SqStack S){
    return (S.top == MAXSIZE-1? true:false);
}

// 进栈
int Push(SqStack &S, DataType e){
    if (StackFull(S)) return ERROR;
    S.top++;
    S.data[S.top] = e;
    return true;
}

// 出栈
int Pop(SqStack &S, DataType &e){
    if(StackEmpty(S)) return ERROR;
    e = S.data[S.top];
    S.top--;
    return true;
}

DataType GetTop(SqStack S){
    // 若栈不为空,则取栈顶元素
    DataType e;
    if(StackEmpty(S)) return ERROR;  // 栈空
    e=S.data[S.top];    // 取出数据,top 不变
    return e;
}

/* 比较两个运算符的优先级 */
char Precede (char a, char b){
    char z;
    if ((b == '+')||(b == '-')||(b == '*')||(b == '/')||(b == '(')||(b == ')')||(b == '=')){
        switch(a){
        case '+':
        case '-':
            if ((b =='*')||(b == '/')||(b == '(')) z = '<';
            else z = '>';
            break;
        case '*':
        case '/':
            if (b == '(') z = '<';
            else z = '>';
            break;
        case '(': 
            if (b == '=') z = 'E';
            else 
                if (b ==')') z = '=';
                else z = '<';
            break;
        case ')':
            if (b == '(') z = 'E';
            else z = '>';
            break;
        case '=':
            if (b == '=') z = '=';
            else 
                if (b == ')') z = 'E';
                else z = '<';
            break;
        }
    }else z = 'E';
    return (z);
}

/* 判断字符 ch 是否为算符 */
int In(char ch){
    int i, flag = 0;
    char op[7] = {'+', '-', '*', '/', '(', ')', '='};
    for (i = 0; i < 7 ; i ++ ) 
        if (ch == op[i]){
            flag = 1;
            break;
        }
    return flag;
}

DataType Operate(DataType a, char theta, DataType b){
    DataType z;
    switch(theta){
    case '+': z = a + b; break;
    case '-': z = a - b; break;
    case '*': z = a * b; break;
    case '/': z = a / b; break;
    }
    return (z);
}

double CaculateExpression(){
    // 算法表达式求值的算符优先算法。设 optr 和 opnd 分别为算符栈和操作数栈
    // OP 为算符集合
    SqStack optr, opnd;
    double x, theta, a, b, sum, count;
    char c;
    c = getchar();
    InitStack(optr);
    Push(optr, (int)'=');
    InitStack(opnd);
    while (c!= '=' || GetTop(optr)!= '='){
        if (In(c)){  // 如果是运算符
            switch(Precede(GetTop(optr), c)){
                case '<': // 栈顶算符优先级低
                    Push(optr, c); c = getchar();
                    break;
                case '=': // 优先级相同, 脱去括号病读入下一个字符
                    Pop(optr, x); c = getchar();
                    break;
                case '>': // 栈顶算符优先级高, 退栈并将运算结果入栈
                    Pop(optr, theta);
                    Pop(opnd, b); Pop(opnd, a);
                    Push(opnd, Operate(a, theta, b));
                    break;
            }
        } else {  // 如果是数字
            double num = 0;
            while (c >= '0' && c <= '9'){  // 连续读取数字字符
                num = num * 10 + c - '0';
                c = getchar();
                if (c == '.')
                {
                	count ++;
                	c = getchar();
				}
            }
            num = num / pow(10, count);
            Push(opnd, num);  // 将数字入操作数栈
            count = 0;
        }
    }
    return GetTop(opnd);
}

int main(){
    printf("%lf",CaculateExpression());  // 将输出格式改为 %f 以输出浮点数
    return 0;
}

欢迎订阅专栏,数据结构实验,期末大作业,前端后端都有哦,想我发哪个方面的资源或文章可以私信我,免费的哦

一、问题描述 在控制台下实现一个对算术表达式求值的模拟程序。 二、基本要求 该演示程序具有如下基本功能: (1) 表达式输入,以字符序列的形式从终端输入一个语法正确的数值表达式(float型),且表达式中只含有+、-、*、/、( 、)6 种运算符,输入格式如下: <变量><运算符><变量>……<回车> 例如表达式: 100+(15/3)*2 输入格式为: 100+(15/3)*2<回车> 注意: 输入的表达式中间不含空格。 (2) 表达式结果的输出,输出形式为: <表达式> = <结果> 例如表达式: 100+(15/3)*2 输出形式为: 100+(15/3)*2 = 110 注意: 此处的输出结果为整个表达式的数值结果。 (3) 数据合法性检验 主要是针对原表达式中除数为 0 的情况。 三、界面效果 表达式求值模拟程序 功能菜单: ============== [1] 输入表达式并求值 [0] 退出 ============== 请输入你的选择 (0~1):1 请输入一个表达式 : 100+(15/3)*2 计算结果如下: 100+(15/3)*2 = 110 请输入你的选择 (0~1):0 四、测试数据 (1) 8 = (2) 1+2+3+4 = (3) 88-1*5 = (4) 1024/4*8 = (5) 1024/(4*8) = (6) (20+2)*(6/2) = (7) 3-3-3 = (8) 80/(9-9) = (9) (6+2*(3+6*(6+6)) = (10) (((6+6)*6+3)*2+6)*2 = 五、实现提示 (1) 设置运算符和操作数辅助分析算符优先关系; (2) 在读入字符序列时,完成运算符和操作数的处理,以及相应运算; (3) 在识别处运算数的同时,要将其字符序列形式转化成 float 型数据形式; (4) 输入的字符序列中,操作数不一定是一位数,可能是多位数,如 16+32 ; (5) 使用 Lab3-1 实现的的 ADT 基本操作完成本次作业 ; (6) 在程序中会用到两类:操作数和运算符,分别为 float 型数据和字符型数据, 思考在同一个程序中如何处理两类不同的数据类型? (7) 算符之间的优先关系参考课本 P53 页表 3.1 。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

然然超绝肌肉线条

你的鼓励将是创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值