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++知识库]中缀表达式求值

根据输入的中缀表达式构造一棵等价的中缀表达式树,并通过此树计算中缀表达式的值。


通过中缀表达式树计算中缀表达式

一、构造中缀表达式树:

①初始化操作数栈运算符栈

②扫描中缀表达式:

  • 若扫描到操作数,压入操作数栈;
  • 若扫描到界限符,遇到(直接压入运算符栈,遇到)依次弹出运算符栈内运算符,直到弹出(
  • 若扫描到运算符,依次弹出运算符栈中优先级高于或等于当前运算符的所有运算符,直到遇到(或运算符栈空,之后再将当前运算符压入运算符栈;
  • 若扫描到等于号,依次弹出运算符栈中的所有运算符。
  • 同时:a.每次压栈时,将操作数或运算符转化为二叉树结点形式再压栈。b.每当运算符栈中弹出运算符时,依次弹出操作数栈中的两个元素作为右操作数左操作数,分别挂在当前运算符结点的左右孩子处,之后将当前子树作为一个操作数压入操作数栈

二、通过后序遍历递归计算中缀表达式树。


输入样例:
1+2+3*(4+5)=
1+(2+4*4/2)-1=
((9/(5-(1+1)))*3)-(2+(1+1))=
=

输出样例:
30
10
5


在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


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

#define MaxSize 10
#define ElemType BiTree

typedef struct BiTNode {
    char data;
    struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;

typedef struct SqStack {
    ElemType data[MaxSize];
    int top;
} SqStack;

BiTree BiTreeCreate(char *nodeData);
void BiTreeDestroy(BiTree *root);
BiTNode *nodeCreate(char c);

int calculate(BiTree root);
bool isLessOrEqual(char c1, char c2);

/*为简化代码,所有的栈操作都不作出错检查*/
void StackInit(SqStack *stack);
bool StackEmpty(SqStack stack);
void StackPush(SqStack *stack, ElemType e);
ElemType StackPop(SqStack *stack);
ElemType StackGetTop(SqStack stack);

int main() {
    char str[MaxSize] = "";

    while (scanf("%[^\n]%*c", str) && str[0] != '=') {
        BiTree T = NULL;

        T = BiTreeCreate(str);
        printf("%d\n", calculate(T));

        BiTreeDestroy(&T);
    }
    return 0;
}

/**
 * 根据中序表达式构造二叉表达式树
 */
BiTree BiTreeCreate(char *nodeData) {
    SqStack numStack;//操作数栈
    SqStack opStack;//运算符栈
    BiTNode *op;//用于暂存出栈的运算符

    StackInit(&numStack);
    StackInit(&opStack);

    for (int i = 0; nodeData[i] != 0; i++) {
        if (nodeData[i] >= 48 && nodeData[i] <= 57) {
            /*当前结点是操作数,直接压操作数栈*/
            StackPush(&numStack, nodeCreate(nodeData[i]));
        } else if (nodeData[i] == '+' || nodeData[i] == '-' || nodeData[i] == '*' || nodeData[i] == '/') {
            if (!StackEmpty(opStack)) {
                op = StackGetTop(opStack);
                if (isLessOrEqual(nodeData[i], op->data)) {
                    /*当前运算符优先级低于或等于栈顶运算符,将栈顶运算符出栈并运算*/
                    op = StackPop(&opStack);
                    /*将左、右操作数挂在左、右孩子位置上的过程就相当于运算*/
                    op->rchild = StackPop(&numStack);
                    op->lchild = StackPop(&numStack);
                    /*运算结果相当于一个操作数*/
                    StackPush(&numStack, op);
                }
            }
            StackPush(&opStack, nodeCreate(nodeData[i]));
        } else if (nodeData[i] == '(') {
            /*左括号直接压栈*/
            StackPush(&opStack, nodeCreate(nodeData[i]));
        } else if (nodeData[i] == ')') {
            /*如果遇到右括号,运算符栈一直出栈并运算,直到左括号出栈*/
            while (1) {
                op = StackPop(&opStack);
                if (op->data != '(') {
                    op->rchild = StackPop(&numStack);
                    op->lchild = StackPop(&numStack);
                    StackPush(&numStack, op);
                } else {
                    break;
                }
            }
        } else {
            /*遇到等号将栈中剩余运算符出栈运算,并将结果返回*/
            while (!StackEmpty(opStack)) {
                op = StackPop(&opStack);
                op->rchild = StackPop(&numStack);
                op->lchild = StackPop(&numStack);
                StackPush(&numStack, op);
            }
            return op;
        }
    }
}

/**
 * 释放二叉树内存空间
 */
void BiTreeDestroy(BiTree *root) {
    if (*root) {
        BiTreeDestroy(&(*root)->lchild);
        BiTreeDestroy(&(*root)->rchild);
        free(*root);
        *root = NULL;
    }
}

/**
 * 将输入数据转化为二叉树结点
 */
BiTNode *nodeCreate(char c) {
    BiTNode *newNode = (BiTNode *) malloc(sizeof(BiTNode));

    newNode->data = c;
    newNode->lchild = newNode->rchild = NULL;
    return newNode;
}

/**
 * 通过表达式树进行计算
 */
int calculate(BiTree root) {
    if (root) {
        switch (root->data) {
            case '+':
                return calculate(root->lchild) + calculate(root->rchild);
            case '-':
                return calculate(root->lchild) - calculate(root->rchild);
            case '*':
                return calculate(root->lchild) * calculate(root->rchild);
            case '/':
                return calculate(root->lchild) / calculate(root->rchild);
            default:
                return root->data - 48;
        }
    }
}

/**
 * 判断c1的优先级是否小于c2
 */
bool isLessOrEqual(char c1, char c2) {
    int priority1 = 1, priority2 = 1;

    if (c1 == '(') {
        priority1 = 0;
    } else if (c1 == '*' || c1 == '/') {
        priority1 = 2;
    }

    if (c2 == '(') {
        priority2 = 0;
    } else if (c2 == '*' || c2 == '/') {
        priority2 = 2;
    }

    return priority1 <= priority2;
}

/**
 * 初始化栈
 */
void StackInit(SqStack *stack) {
    stack->top = -1;
}

/**
 * 判栈空
 */
bool StackEmpty(SqStack stack) {
    return (stack.top == -1) ? true : false;
}

/**
 * 入栈
 */
void StackPush(SqStack *stack, ElemType e) {
    stack->data[++stack->top] = e;
}

/**
 * 出栈
 */
ElemType StackPop(SqStack *stack) {
    return stack->data[stack->top--];
}

/**
 * 取栈顶元素但不出栈
 */
ElemType StackGetTop(SqStack stack) {
    return stack.data[stack.top];
}
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-03-21 20:30:29  更:2022-03-21 20:33:03 
 
开发: 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 3:03:37-

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