逆波兰表达式求值(C语言实现)

2023-11-19

实验项目:

  1. 从文本文件输入任意一个语法正确的(中缀)表达式,显示并保存该表达式。
  2. 利用栈结构,把上述(中缀)表达式转换成后缀表达式,并显示栈的状态变化过程和所得到的后缀表达式。
  3. 利用栈结构,对上述后缀表达式进行求值,并显示栈的状态变化过程和最终结果。

备注:读文件的输入为(以'#'起始和结尾):

#10+13*10+5%2+2^3+(5+6)*7#

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define MAX_LEN 30
#define  MAX 100
//栈的数组实现
typedef struct
{
    int data[MAX_LEN];
    int top;
}Stack;
//为栈分配空间
Stack *Createstack()
{
    Stack *p;
    p = (Stack *)malloc(sizeof(*p));
    p->top = -1;
    return p;
}
//压栈
int Push(Stack *p,int x)
{
    if (p->top == MAX_LEN - 1)
    {
    return -1;
    }
    p->top++;
    p->data[p->top] = x;
    return 0;
}
//出栈
int Pop(Stack *L,int *x)
{
    if (L->top == -1)
    {
    return -1;
    }
    //利用传出参数传出栈顶元素
    *x = L->data[L->top];
    L->top--;
    return 0;
}
//栈顶
int TOP(Stack *L,int *x)
{
    if (L->top == -1)
    {
    return -1;
    }
    *x = L->data[L->top];
    return 0;
}
//判断栈是否为空
int Empty(Stack *L)
{
    return (L->top == -1);
}
//定义符号的优先级
int Priority(int ope)
{
    switch(ope)
    {
    case '(':   return 0;  //左括号已经在栈内时,如果比较,其优先级最低
    case '+':
    case '-':   return 1;
    case '*':
    case '%':
    case '/':   return 2;
    case '^':  return 3;
    default :   return -1;
    }
}
// 将两个数出栈、根据ope符号计算,然后再次入栈
void Calculation(Stack *snum,int ope)
{
    int n,n1,n2;
    Pop(snum,&n1);
    Pop(snum,&n2);
    switch(ope)
    {
        case '+':   n = n1 + n2; break;
        case '-':   n = n2 - n1; break;
        case '*':   n = n1 * n2; break;
        case '/':   n = n2 / n1; break;
        case '%':   n = n2 % n1; break;
        case '^':   n = pow(n2,n1);break;
    }
    Push(snum,n);
}
// 先处理除右括号外的符号
void Deal_ope(Stack *snum,Stack *sope,int ope)
{
    int old_ope;
    if (Empty(sope) || ope == '(')
    {
        Push(sope,ope);
        return ;
    }
    TOP(sope,&old_ope);
    if (Priority(ope) > Priority(old_ope))
    {
        //传入符号大于当前栈顶,则将传入符号入栈
        Push(sope,ope);
        return ;
    }
    //如果传入的符号优先级小于当前栈顶符号
    while (Priority(ope) <= Priority(old_ope))
    {
        //将当前栈顶的符号取出与数字栈中顶端的两个数字进行计算
        Pop(sope,&old_ope);
        printf("%c ",old_ope);
        Calculation(snum,old_ope);
        if (Empty(sope))
        {
            break;
        }
        //再次取出一个当前栈符号与传入符号比较,循环
        TOP(sope,&old_ope);
    }
    Push(sope,ope);
}
//单独处理右括号
void Right(Stack *snum,Stack *sope)
{
    int old_ope;
    TOP(sope,&old_ope);
    while (old_ope != '(')
    {
        //当前符号出栈然后将数字出栈两个进行计算,在括号内优先级最高
        Pop(sope,&old_ope);
        printf("%c ",old_ope);
        Calculation(snum,old_ope);
        //循环
        TOP(sope,&old_ope);
    }
    Pop(sope,&old_ope);//出现左括号时将它丢弃
}
// 打印数字栈
void Display(Stack *L)
{
    int i;
    if (L->top == -1)
    {
    return ;
    }
    for (i = 0 ; i <= L->top; i++)
    {
    printf("%d ",L->data[i]);
    }
    printf("\n");
}
//打印符号栈
void Displayope(Stack *L)
{
    int i;
    if (L->top == -1)
    {
    return ;
    }
    for (i = 0 ; i <= L->top; i++)
    {
    printf("%c ",L->data[i]);
    }
    printf("\n");
}
/*从文件中读入中缀表达式*/
void Readexpression(char a[])
{
    char x[MAX_LEN];
    int i=1,j=0;
    FILE *fp;
    fp=fopen("char.txt","r+b");
    if(fp==NULL)
    {
        printf("char.txt can not be read!\n");
        exit(0);
    }
    fscanf(fp,"%s",x);
    fclose(fp);
    for(i=1;x[i]!='#';i++)
    {
        a[j]=x[i];
        j++;
    }
    a[j]='\0';
}

int main()
{
    char str[MAX],dst[MAX];
    printf("中缀表达式为:");
    Readexpression(str);
    printf("%s\n",str);
    int i = 0,value = 0,flag = 0;   //数字的值
    int old_ope;
    Stack *numstack,*opestack;
    numstack = Createstack();  // 创建存放数字的栈
    opestack = Createstack();  // 创建存放运算符的栈
    printf("后缀表达式为:");
    //printf("栈的变化如下:\n");
    /* 表达式字符串解析函数,然后将高优先级的符号/(*)进行计算重新入栈
       退出while大家的优先级都一样*/
    while (str[i] != '\0')
    {
        if (str[i] >= '0' && str[i] <= '9')
        {
            value *= 10;        //数字的获取,注意可能不止一位
            value +=str[i]-'0';
            flag = 1;
        }
        else
        {
            if (flag)   //flag = 1说明value里面存储了数字,将其入栈
            {
                printf("%d ",value);
                Push (numstack, value);
                //flag标志清零,value存放数字的变量清零
                flag = 0;
                value = 0;
                //Display(numstack);
            }
            if(str[i] == ')')
            {
                Right(numstack,opestack);
                //Displayope(opestack);
            }
            else
            {
                Deal_ope(numstack,opestack,str[i]);
                //Displayope(opestack);
            }
        }
        i++;
    }
    if (flag)   //如果flag = 1.说明value里面还有数值,将其入栈
    {
        printf("%d ",value);
        Push(numstack,value);
        //Display(numstack);
    }
    while (!Empty(opestack))  //如果符号栈不为空,继续计算
    {
        Pop(opestack,&old_ope);
        printf("%c ",old_ope);
        Calculation(numstack,old_ope);
        //Displayope(opestack);
    }
    Pop(numstack,&value); //最终答案
    printf("\n%s = %d\n",str,value);
    return 0;
}

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

逆波兰表达式求值(C语言实现) 的相关文章

  • 以OpenGL/ES视角介绍gfx-hal(Vulkan) Shader/Program接口使用

    文档列表见 Rust 移动端跨平台复杂图形渲染项目开发系列总结 目录 背景 The right way to tackle this in Vulkan is to use resource descriptors A descriptor
  • LeetCode83: 删除排序链表中的重复元素

    给定一个已排序的链表的头 head 删除所有重复的元素 使每个元素只出现一次 返回 已排序的链表 示例 1 输入 head 1 1 2 输出 1 2 示例 2 输入 head 1 1 2 3 3 输出 1 2 3 提示 链表中节点数目在范围
  • PCL—低层次视觉—点云分割(RanSaC)

    点云分割 点云分割可谓点云处理的精髓 也是三维图像相对二维图像最大优势的体现 不过多插一句 自Niloy J Mitra教授的Global contrast based salient region detection出现 最优分割到底鹿死
  • 数据结构与算法学习总结(六)——字符串的模式匹配算法

    基本概念 字符串是一种特殊的线性表 即元素都是 字符 的线性表 字符是组成字符串的基本单位 字符的取值依赖于字符集 例如二进制的字符集为0 1 则取值只能为 0 1 再比如英语语言 则包括26个字母外加标点符号 例如 abcde 就是一个字
  • 递归算法中的时间复杂度分析

    对于一种算法的时间复杂度分析还是特别重要的 在一些非递归算法中 我们仅仅看运算次数最多的那一行代码可能执行多少次就可以 实际就是看在循环中变量的变化 但是对于递归算法中该怎么分析呢 下面介绍几种递归函数中的算法时间复杂度分析的方法 0 递推
  • Hash映射理解

    先说数组 数组优点之一 能通过索引很快定位到值 hashmap 就是利用了数组这个优点 对比 线性映射 定义一个数组 数组的元素是结构体 结构体包括 一对键 值 伪代码表示 a 0 struct Bill 5 a 1 struct KK 6
  • 亚利桑那州立大学周纵苇:研习 U-Net ——现有的分割网络创新

    雷锋网AI研习社按 经典的 Encoder Decoder 结构在目标分割问题中展现出了举足轻重的作用 然而这样一个相对固定的框架使得模型在感受野大小和边界分割精度两方面很难达到兼顾 本次公开课 讲者以 U Net 为案例分析 总结现有的分
  • 数据结构之图的两种遍历实现(C语言版)

    上一期文章分享完了图的两种遍历方式 也是两种很重要的算法 DFS和BFS 这两种算法的应用和重要性我就不多说了 内行的人懂的都懂 今天这文章重要就是来上机实现这两种算法 又由于这两种算法都可以由邻接矩阵和邻接表来表示 博主分享的代码都是上机
  • 字符串09--表示数值的字符串

    字符串09 表示数值的字符串 jz53 题目概述 解析 参考答案 注意事项 说明 题目概述 算法说明 请实现一个函数用来判断字符串是否表示数值 包括整数和小数 例如 字符串 100 5e2 123 3 1416 和 1E 16 都表示数值
  • JavaScript系列——数组元素左右移动N位算法实现

    引言 在自己刚刚毕业不久的时候 去了一家公司面试 面试官现场考了我这道题 我记忆深刻 当时没有想到思路 毫无疑问被面试官当成菜鸟了 最近刚好在研究数组的各种算法实现 就想到这道题 可以拿来实现一下 纪念自己逝去的青春 需求 假设有这样一个数
  • Linux 内核中的 Device Mapper 机制

    Linux 内核中的 Device Mapper 机制 尹 洋 在读博士生 尹洋 中科院计算所国家高性能计算机工程技术研究中心的在读博士生 主要从事服务部署和存储资源管理以及Linux块设备一级的开发和研究工作 简介 本文结合具体代码对 L
  • 机器学习算法GBDT的面试要点总结-上篇

    1 简介 gbdt全称梯度提升决策树 在传统机器学习算法里面是对真实分布拟合的最好的几种算法之一 在前几年深度学习还没有大行其道之前 gbdt在各种竞赛是大放异彩 原因大概有几个 一是效果确实挺不错 二是即可以用于分类也可以用于回归 三是可
  • 区块链中的哈希算法

    区块链中的密码学 密码学在区块链中的应用主要有两个 哈希算法与非对称加密算法 这次主要对哈希算法进行详细的说明 哈希算法 哈希算法的特点有 1 输入可以为任意大小的字符串 2 产生固定大小的输出 3 可以在合理的时间内算出输出值 若要满足密
  • 二叉树结构的建立与遍历

    实验项目 1 编写建立二叉树的二叉链表存储结构 左右链表示 的程序 并以适当的形式显示和保存二叉树 2 完成二叉树的7种遍历操作 3 给定一个二叉树 编写算法完成下列应用 1 判断其是否为完全二叉树 2 求二叉树中任意两个结点的公共祖先 输
  • 雪糕的最大数量 排序+贪心

    雪糕的最大数量 雪糕的最大数量 题目描述 样例 数据范围 思路 代码 题目描述 夏日炎炎 小男孩 Tony 想买一些雪糕消消暑 商店中新到 n 支雪糕 用长度为 n 的数组 costs 表示雪糕的定价 其中 costs i 表示第 i 支雪
  • 牛客剑指offer刷题其他算法篇

    文章目录 构建乘积数组 题目 思路 代码实现 第一个只出现一次的字符
  • 数组实现循环队列(增设队列大小size)

    目录 一 前言 1 如何实现循环 2 如何判断队列为空 3 如何判断队列为满 二 循环队列的结构定义 三 循环队列的创建及其初始化 四 入队 五 出队 六 取队头元素 七 取队尾元素 八 循环队列判空 九 循环队列判满 十 循环队列销毁 一
  • 【数据结构入门精讲 | 第二篇】一文讲清算法复杂度

    上篇文章中我们引入了算法 数据结构 数据类型等概念 而要想衡量一个算法与数据结构是否为优质的 就需要一个衡量标准 这个衡量标准也是在我们实现一个好的算法时要遵循的原则 目录 基本概念 渐进性态 渐进性态数学表征 算法复杂度的运算 顺序搜索算
  • C++ AVL树(四种旋转,插入)

    C AVL树 四种旋转 插入 一 AVL树的概念及性质 二 我们要实现的大致框架 1 AVL树的节点定义 2 AVL树的大致框架 三 插入 1 插入逻辑跟BST相同的那一部分 2 修改平衡因子
  • 最大流-Dinic算法,原理详解,四大优化,详细代码

    文章目录 零 前言 一 概念回顾 可略过 1 1流网络 1 2流 1 3最大流 1 4残留网络 1 5增广路

随机推荐

  • Day 2 – 布尔值,字符串插值

    如何创建布尔值 布尔值是一种数据类型 用于存储逻辑真假值 在Swift中 布尔值用true和false表示 布尔值通常用于控制程序的流程和逻辑 let goodDogs true let gameOver false let isMulti
  • Active Directory 与域

    1工作场景导入 工作场景 XYZ公司是一家大型制造企业 公司有许多内设部门 车间和分厂 在全国各地有许多分公司 该公司总部信息中心有各类服务器30余台 各车间 分厂和分公司都有自己的服务器 客户机近千台 目前 该公司的各类应用大多基于Win
  • linux 查看JVM默认参数 (centos7)

    情景 之前学习过 深入了解JVM虚拟机 习得了一些JVM方面的一些知识 但是并没有相应的实战 虽然没有相应的实战 但是 咱们也得知道如何查看JVM默认参数 以及如何修改相应的JVM参数 查看命令 1 显示出JVM初始化完毕后所有跟最初的默认
  • C语言:递归实现输出一个整数的逆序

    任务描述 题目描述 编写一个递归函数 将一个整数n逆序输出 比如 n 12345 输出54321 相关知识 略 编程要求 请仔细阅读右侧代码 结合相关知识 在Begin End区域内进行代码补充 输入 一个整数n 输出 该整数的逆序 测试说
  • 蓝桥杯.卡片(模拟)

    Question Result 3181 Solve 直接模拟暴力 初始化卡片数量为2021 去模拟拼数的过程 注意点的话 我是先去判断卡片还有没有 再去减一 所以输出结果也有一个减一 因为一旦说卡片没有了 就意味着当前这个数字拼不成了 C
  • chmod 777 权限恢复问题 /etc/sudoers.d

    etc sudoers d问题 2016年07月27日 15 09 45 阅读数 1130 下述问题是由于我更改了整个 etc文件夹的权限后产生的 问题描述 sudo etc sudoers 可被任何人写 sudo no valid sud
  • tpcc mysql下载_TPCC安装和压测数据库数据表创建生成

    下载TPCC mysql root cnbugs1 git clone https github com Percona Lab tpcc mysql git 配置TPCC mysql root cnbugs1 mv tpcc mysql
  • C语言常见问题

    问题1 sizeof与strlen区别 1 sizeof sizeof 是一种单目操作符 是用来计算你所使用的操作数所占的空间字节大小 可以以类型 指针 数组和函数等作为参数 返回值类型为unsigned int 2 strlen strl
  • 面向对象高级特性

    static的含义 继承的规则 子类实例化的过程 方法的覆盖 final关键字 抽象类的特性 接口的规范 静态修饰符static static可以修饰的元素 属性 共享 方法 访问的方式 块 执行的时机 只能修饰类成员 不能修饰局部变量 静
  • vue聊天页面在进入之后信息滑动到底部位置

    这是需要实现的目标 怎么做到进入到页面之后就滑动到底部 借助两个属性 scrollHeigh 该属性是指 元素中内容 的高度 图中的意思就是全部信息所占用的总高度 scrollTop 指的是 元素中的内容 超出 元素上边界 的那部分的高度
  • Python数据可视化详解(3/5)--------patch,饼图,柱状图和点图

    水平或垂直的单条柱状图 如图 上代码 import matplotlib pyplot as plt import numpy as np fig axes plt subplots 2 1 x 1 2 3 4 5 6 data 5 4 1
  • Redis高级客户端Lettuce详解

    前提 Lettuce是一个Redis的Java驱动包 初识她的时候是使用RedisTemplate的时候遇到点问题Debug到底层的一些源码 发现spring data redis的驱动包在某个版本之后替换为Lettuce Lettuce翻
  • 测试用例的基本要素 && properties配置文件 && 测试用例的基本要素 && SpringMVC背景知识 && 按照开发阶段划分测试类型

    第 1 题 简答题 题目名称 设计测试用例 登陆页面 题目内容 请你针对登陆场景来设计测试用例 记得用脑图哦 第 2 题 简答题 题目名称 测试用例设计 淘宝购物车 题目内容 设计淘宝购物车的测试用例 尽可能多的来设计测试用例 若想不出来了
  • DataGrip配置设定

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 前言 一 下载安装 二 使用步骤 1 配置成中文 2 导入旧的设定 3 常用操作 总结 前言 提示 这里可以添加本文要记录的大概内容 更换电脑 重装DataGrip
  • java通过word模板生成导出word

    java通过word模板生成导出word 生成word方法类 public class BokeWordUtils 根据模板生成新word文档 判断表格是需要替换还是需要插入 判断逻辑有 为替换 表格无 为插入 param inputUrl
  • MYSQL数据库转化成H2数据库

    mysql数据库数据导成CSV文件 H2 数据库导入CSV文件 代码如下 insert into tableName select from csvread c import data csv
  • DBCP 应用的总结(一)

    DBCP 应用的总结 1 Jar包下载 首先 下载必须的jar包 dbcp包 http jakarta apache org commons dbcp pool包 http jakarta apache org commons pool 如
  • POJ 2676 Sudoku 数独(dfs)

    POJ 2676 Sudoku 数独 dfs Sudoku is a very simple task A square table with 9 rows and 9 columns is divided to 9 smaller squ
  • Java jvm 内存溢出分析

    1 如何分析jvm内存溢出呢 我们经常用visualVm监控Jvm的内存 cpu 线程的使用情况 通常可以根据内存不断增长来判断内存是否存在不释放 但是我们不可能时时盯着去看 这里涉及jvm堆内存配置 堆内存参数配置和调优会在其他章节编写
  • 逆波兰表达式求值(C语言实现)

    实验项目 从文本文件输入任意一个语法正确的 中缀 表达式 显示并保存该表达式 利用栈结构 把上述 中缀 表达式转换成后缀表达式 并显示栈的状态变化过程和所得到的后缀表达式 利用栈结构 对上述后缀表达式进行求值 并显示栈的状态变化过程和最终结