IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 数据结构严蔚敏C语言版栈数据结构课后练习——表达式求值 -> 正文阅读

[C++知识库]数据结构严蔚敏C语言版栈数据结构课后练习——表达式求值

【题目】

任何一个表达式都由操作数、运算符和界限符组成的,为了叙述的简洁,在此仅讨论简单算数表达式的求值问题,这种表达式只包含加、减、乘、除4种运算符。
例如:
控制台输入 2*(2+3)-5+4*5
控制台输出 25

我们知道,算术四则运算遵循以下3条规则:
1、先乘除后加减
2、从左到右运算
3、先括号内后括号外

【思路分析】

1、通过for循环索引来遍历我们输入的表达式
2、如果索引处的值是数字就直接压入数字栈
3、如果索引处的值是运算符分两种情况
3.1、如果符号栈为空就直接入栈
3.2、如果符号栈中有运算符,将当前运算符优先级与栈顶运算符的优先级比较。如果当前运算符优先级小于或等于栈顶运算符的优先级,就需要从数字栈中弹出两个数并从符号栈中弹出一个运算符。进行运算后将结果入数字栈,循环直至当前运算符优先级大于栈顶运算符的优先级将,然后当前运算符入符号栈。如果当前运算符优先级大于栈顶运算符的优先级,就直接入符号栈。如果是"(“号就直接入符号栈,如果是”)"就从数字栈中弹出两个数并从符号栈中弹出一个运算符。进行运算后将结果入数字栈,循环这个操作直至遇到")“符号,将”)"符号弹出。
4、当表达式扫面完毕,就按顺序从数字栈中弹出两个数字从符号栈中弹出一个运算符,将运行结果压入数字栈
5、重复第4不操作直至数字栈中只剩一个数字,这个数字就是表达式的结果

【完整代码】

#include<iostream>
#include <string>
#define OK 1
#define ERROR 0
#define MAXSIZE 100
using namespace std;
typedef int Status;
typedef int SElemType;

typedef struct {
    SElemType* base;//栈低指针
    SElemType* top;//栈顶指针
    int stackSize;//栈可用最大容量
}SqStack;

/**
 *初始化顺序栈
 */
Status InitStack(SqStack &s){
    s.base = new SElemType[MAXSIZE];//为顺序栈动态分配一个最大容量为MAXSIZE的数组空间
    if(!s.base) exit(ERROR);
    s.top = s.base;
    s.stackSize = MAXSIZE;
    return OK;
}
/**
 *入栈
 * */
Status Push(SqStack &s,SElemType e){
    if(s.top-s.base == s.stackSize)//为什么不s.top>s.stackSize 因为s.top是指针s.stackSize是int
        return ERROR;
    *s.top=e;//*解引用
    s.top ++;
    return OK;
}
/**
 *弹栈
 * */
Status Pop(SqStack &s,SElemType &e){
    if (s.top == s.base)
        return ERROR;
    s.top--;
    e = *s.top;
    return OK;
}
/**
 *取出栈顶元素
 * */
SElemType GetTop(SqStack &s){
    if(s.top == s.base) return ERROR;
    return *(s.top-1);
}
/**
 *运算符优先级
 * */
int priority(int oper){
    if (oper == '*' || oper == '/') return 1;
    else if (oper == '+' || oper == '-') return 0;
    else if (oper == '(' || oper == ')') return 2;
    else return -1;
}
/**
 *从数字栈中弹出两个数并从符号栈中弹出一个运算符并进行运算返回运行结果
 * */
int operatorNum(SqStack &numStack,SqStack &operatorStack){
    int right,left,oper1;
    Pop(numStack,left);
    Pop(numStack,right);
    Pop(operatorStack,oper1);
    switch (oper1){
        case 42 :return right*left;
        case 43:return right+left;
        case 45:return right-left;
        case 47:return right/left;
    }
}
void noSingle(string num,SqStack &numStack){
    for (int j = 0; j < num.length(); ++j) {
        int i;
        Pop(numStack, i);
    }
    Push(numStack, atoi(num.c_str()));//string转int
}
int main(){
    string input;
    cin>>input;
    SqStack numStack;
    SqStack operatorStack;
    InitStack(numStack);
    InitStack(operatorStack);
    string num;
    for (int i = 0; i <input.length(); i++) {
        if (48<=input[i] && input[i]<=57){
            //是数字
            Push(numStack,input[i]-48);
            string str(1,input[i]);//char转string
            num.append(str);
            if(i == input.length()-1 && num.length()>=2)
                noSingle(num,numStack);
        }else{
            if (num.length()>=2)
                noSingle(num,numStack);
            num = "";
            //是操作符且栈为空
            if (operatorStack.top == operatorStack.base)
                Push(operatorStack,input[i]);
            else{//栈不为空
                SElemType oper = GetTop(operatorStack);
                if(input[i] == ')'){
                    while(oper != '('){
                        int result = operatorNum(numStack,operatorStack);
                        Push(numStack,result);
                        oper = GetTop(operatorStack);
                    }
                    Pop(operatorStack,oper);
                }else if (priority(input[i]) <= priority(oper) && priority(oper) != 2){
                    while (priority(input[i]) <= priority(oper)){
                        int result = operatorNum(numStack,operatorStack);
                        Push(numStack,result);
                        oper = GetTop(operatorStack);
                    }
                    Push(operatorStack, input[i]);
                }
                else{
                    Push(operatorStack, input[i]);
                }
            }
        }
    }
    while (numStack.top != numStack.base+1){
        int result = operatorNum(numStack,operatorStack);
        Push(numStack,result);
    }
    int result = GetTop(numStack);
    cout<<"结果="<<result;
    return 0;
}

【运行结果】

2*(2+3)-5+4*5
结果=25
Process finished with exit code 0
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-03-24 00:18:35  更:2022-03-24 00:19:43 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 1:43:01-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码