先用c语言,实现了一个栈结构,中缀表达式 转换成 后缀表达式  , 在用栈完成逆波兰表达式计算。  最后写了一些测试用例  验证.

中缀表达式是最常用的算术表达式,运算符在运算数中间,运算需要考虑运算符优先级.
后缀表达式是计算机容易运算的表达式,运算符在运算数后面,从左到右进行运算,无需考虑优先级,运算呈线性结构.
先举个简单的转换例子
2+9/3-5 (中缀)-> 2 9 3 / + 5 - (后缀)
先进行乘除再进行加减
运算规律,运算数位置不变,改变的是运算符位置
可以推栈实现,用堆栈储存等待中的运算符.
将当前运算符与最后一个等待的运算符比较.

具体转换方式:
1.从左到右进行遍历
2.运算数,直接输出.
3.左括号,直接压入堆栈,(括号是最高优先级,无需比较)(入栈后优先级降到最低,确保其他符号正常入栈)
4.右括号,(意味着括号已结束)不断弹出栈顶运算符并输出直到遇到左括号(弹出但不输出)
5.运算符,将该运算符与栈顶运算符进行比较,
如果优先级高于栈顶运算符则压入堆栈(该部分运算还不能进行),
如果优先级低于等于栈顶运算符则将栈顶运算符弹出并输出,然后比较新的栈顶运算符.
(低于弹出意味着前面部分可以运算,先输出的一定是高优先级运算符,等于弹出是因为同等优先级,从左到右运算)
直到优先级大于栈顶运算符或者栈空,再将该运算符入栈.
6.如果对象处理完毕,则按顺序弹出并输出栈中所有运算符.

#import <Foundation/Foundation.h>
#include <stdio.h>
#include <stdlib.h>typedef struct Node{double data;struct Node * next;
} Node;typedef struct Stack{Node * data; // 存的是栈顶的元素int count;
} Stack;Stack * s ;
// 生成栈
void initStack(){s = (Stack *)malloc(sizeof(Stack));s->count = 0;s->data = NULL;
}// 入栈,push
void push(double data){printf("%f  即将被入栈\n",data);Node * n = malloc(sizeof(Node));n->data = data;n->next = s->data;s->data = n;s->count ++;
}// 出栈,pop
double pop(){if(s->data == NULL){printf("已经是空栈了\n");return CGFLOAT_MAX;}Node * n = s->data;double r = n->data;printf("数据 %f  即将出栈\n",n->data);s->data=n->next;free(n);s->count--;return  r;}// 清空栈
void clearStack(){while (s->data != NULL){pop();}
}// 获取栈顶元素
double topItem(){if (s->data==NULL){printf("此栈为空栈\n");return CGFLOAT_MAX;}printf("此栈中元素数量为 %d 个,栈顶为 %f\n",s->count,s->data->data);return s->data->data;}// 把字符串转成double,没有做错误检测,比如用户输入 12.35.5 5abc.64,就会出错。
double charToDouble(char * num){double a = 0.0;// 把一个字符串转成浮点型数字,记录小数点后的位数,忽略小数点转成整数,// 然后用这个整数 除以小数点后的位数,即可得到浮点数,比如字符串"12.35"->先变成1235,记录有小数点,小数点有2位->在转成12.35int havePoint = 0; //这个数中是否有小数点int j=0; // 记录小数点后面有几位的for(int i=0; num[i]!='\0'; i++){if(num[i]=='.'){havePoint = 1;continue;}if(havePoint==1){j++;}a = a * 10 + num[i] - '0';}while(j>0){a = a/10;j--;}printf("字符串%s 转成 浮点数  %f\n",num,a);return a;}int main(){initStack();// 测试用例
//    char * str = "3*4/2*3"; //18
//    char * str = "3*4+2*3"; //18
//    char * str = "3/9+3"; //3.33
//    char * str = "5*14+2*3"; //76
//    char * str = "(18+2)/10-2"; //0
//    char * str = "2*(7-2)+12"; //22
//    char * str = "2.1*(7-2)+12"; //22.5
//    char * str = "2.1*(7+3)+12"; //33
//    char * str = "2.1/(10-3)+12"; //12.3
//    char * str = "9/(6-3)/2"; //1.5
//    char * str = "6-3+2"; //5char str[100] ;printf("输入一串表达式\n");
//     键盘要换成英文输入,不然无法输入。哭...gets(str);// 记录逆波兰表达式的结果,// 结构是 【0或1】 【对应值】,由于加减乘除 都是char类型,char -> int -> double,所以用double存储。// 0 表示是数字类型, 1 表示后面的是符号类型 ,// 40 = (   41 = )  42 = *  43 = +  45 = -  47 = /double niBoLan[100]={0.0};int niI = 0; // 逆波兰表达式的下标char num[100] = "\0"; // 把字符串导出数字使用,int j = 0;//记录这个数字char的长度,比如 12.3 就会记录为4// 把中缀表达式->后缀表达式,刚开始栈中只保存符号,//从左到右遍历中缀表达式的每个数字和符号,若是数字就输出,即成为后缀表达式的一部分;//若是符号,则判断其与栈顶符号的优先级,是右括号或优先级低于找顶符号(乘除优先加减)则栈顶元素依次出找并输出,并将当前符号进栈,//一直到最终输出后缀表达式为止。for(int i=0; str[i]!='\0'; ){// 区分出是数字还是符号if ((str[i]<='9'&&str[i]>='0') || str[i]=='.'){// 把数字转换出来while ((str[i]<='9'&&str[i]>='0') || str[i]=='.'){char a = str[i];num[j]=a;j++;num[j]='\0';i++;}double b = charToDouble(num);num[0] ='\0';j=0;niBoLan[niI] = 0;niI ++;niBoLan[niI] = b;niI ++;} else {// 是符号,入栈,比较优先级char a = str[i];switch (a) {case '+':case '-':while(topItem()=='*'||topItem()=='/'||topItem()=='+'||topItem()=='-'){niBoLan[niI] = 1;niI ++;niBoLan[niI] = pop();niI++;}push(a);break;case '*':case '/':while(topItem()=='*'||topItem()=='/'){niBoLan[niI] = 1;niI ++;niBoLan[niI] = pop();niI++;}push(a);break;case '(':push(a);break;case ')':while(topItem()!='('){niBoLan[niI] = 1;niI ++;niBoLan[niI] = pop();niI++;}pop(); // 需要把 ( 弹出break;}i++;}}// 栈中剩余的符号弹出while (s->data != NULL){niBoLan[niI] = 1;niI ++;niBoLan[niI] = pop();niI++;}for(int i = 0;i<niI;i++) {printf("%f  ",niBoLan[i]);}printf("\n中缀表达式->逆波兰转换完毕,检查一下\n");clearStack();printf("\n清空栈结构,开始计算结果\n");double num1;double num2;for(int i = 0;i<niI;i+=2) {// 判断标志位, 0 是数字, 1 是符号。int isChar = niBoLan[i];if(isChar == 0 ) {// 数字直接入栈push(niBoLan[i+1]);} else {char a = niBoLan[i+1];switch  (a) {case '+':push( pop() + pop() );break;case '-':num1 = pop();num2 = pop();push( num2 - num1 );break;case '*':push( pop() * pop() );break;case '/':num1 = pop();num2 = pop();push( num2 / num1 );break;}}}printf("\n计算结果 %f\n",pop());}

用c语言做一个栈,完成逆波兰表达式相关推荐

  1. 栈应用-逆波兰表达式(CPP实现简单易懂图解)

    栈应用-逆波兰表达式(后缀表达式) 逆波兰表达式定义: 在由运算符(operator)和操作数(operand)组成的表达式中不使用括号(parenthesis-free)即可表示带优先级的运算关系 ...

  2. Bailian2694 逆波兰表达式(POJ NOI0202-1696, POJ NOI0303-1696)【文本】

    问题链接:POJ NOI0202-1696 逆波兰表达式. 问题链接:POJ NOI0303-1696 逆波兰表达式. 逆波兰表达式 描述 逆波兰表达式是一种把运算符前置的算术表达式,例如普通的表达式 ...

  3. 如何轻松使用 C 语言实现一个栈?​

    作者 | 写代码的篮球球痴 什么是数据结构? 数据结构是什么?要了解数据结构,我们要先明白数据和结构,数据就是一些int char 这样的变量,这些就是数据,如果你是一个篮球爱好者,那么你的球鞋就是你 ...

  4. 逆波兰表达式[栈 C 语言 实现]

    逆波兰表达式 逆波兰表达式又叫做后缀表达式.在通常的表达式中,二元运算符总是置于与之相关的两个运算对象之间,这种表示法也称为中缀表示.波兰逻辑学家J.Lukasiewicz于1929年提出了另一种表示 ...

  5. 用C语言做一个迷宫小游戏

    用C语言做一个迷宫小游戏,以下是代码段 这个迷宫游戏使用了递归回溯算法来寻找通往出口的路径.迷宫中的墙用'#'表示,路径用空格表示,入口和出口分别用'S'和'E'表示,已走过的路径用'*'表示.在生成 ...

  6. C语言栈的运用:后缀表达式(逆波兰表达式)计算器

    原理很简单,当操作者输入中每遇数字便将数字压入数栈,每遇符号便进行两次弹栈进行该符号的运算,运算结果再次压入数栈.唯一要注意的一点就是进行除法运算时需要判断除数是否为0. 头文件: /*Captain ...

  7. 数据结构-栈应用之逆波兰表达式(后缀表达式)

    逆波兰表达式含义我就不做赘述了,摘自百科上的一段话: 逆波兰表达式又叫做后缀表达式.在通常的表达式中,二元运算符总是置于与之相关的两个运算对象之间,这种表示法也称为中缀表示.波兰逻辑学家J.Lukas ...

  8. 数据结构链表之栈——解决括号匹配问题和逆波兰表达式求值问题——6

    括号匹配问题和逆波兰表达式求值问题 基于上一节已经使用python代码对栈进行了简单的实现,这一节我们在其基础上解决两个常见的问题 案例 括号匹配问题(点我直接到代码实现) 逆波兰表达式求值问题(点我 ...

  9. (补)算法训练Day13 | LeetCode150. 逆波兰表达式求值(栈应用);LeetCode239. 滑动窗口最大值(单调队列);LeetCode347. 前K个高频元素(小顶堆,优先级队列)

    目录 LeetCode150. 逆波兰表达式求值 1. 思路 2. 代码实现 3. 复杂度分析 4. 思考 LeetCode239. 滑动窗口最大值 1. 思路 2. 代码实现 3. 复杂度分析 4. ...

  10. 数据结构:栈实现逆波兰计算器

    栈实现逆波兰计算器 前言 上篇博文中已经介绍了栈实现中缀表达式计算器,中缀表达式形如 "1+((2+3)*4)-5" 对人比较容易计算,但对于计算机却是一件比较困难的事,而后缀表达 ...

最新文章

  1. C语言 联合体使用技巧之位带操作
  2. 全球农业发展中国方案-国际农民丰收节贸易会:榜样力量
  3. python宣传图片_宣传图片制作网站
  4. 小米 MIUI 12 Magisk root教程(无需刷REC)
  5. 语法分析:自下而上分析
  6. struts1.x 升级到struts2的几点问题
  7. 使用python查找重复值
  8. 学习java第14天
  9. 【3Dsmax】入门
  10. html滚动条固定前几行,bootstrapTable定位行固定滚动条
  11. Symtavision—分布式嵌入式系统时间建模分析和验证工具
  12. Locust 压力测试工具学习(一)
  13. hint: Updates were rejected because the tip of your current branch is behind(git push线上与本地版本冲突问题)
  14. 一个2层隐层神经网络解决抑或问题
  15. 长微博工具:菊子曰自动微博文字转图片,突破微博140字限制,一键发布完成...
  16. 在前互联网时代,宜家就有这些“互联网思维”
  17. 关于隔离卡的安装系统出现无法转换
  18. 无线通信信号传输模型
  19. 2020第十一届蓝桥杯大赛软件类国赛 C/C++ 大学 B 组
  20. opencv学习日志15-统计焊点个数并输出

热门文章

  1. 2021SC@SDUSC Zxing开源代码(十三)Aztec二维码(二)
  2. 200 行Python 实现的qq连连看 外挂
  3. 解决Win7的svchost进程占内存过大,计算机运行过慢的方法
  4. 计算机二级mysql数据库试题,计算机二级mysql数据库模拟试题及答案.docx
  5. VGA显示器屏幕文字模糊(稍有重影)的解决方案
  6. 1.3.9 快速生成树配置
  7. Dell T40服务器系统安装问题
  8. 抖音seo,抖音优化系统,抖音seo矩阵系统源码技术搭建
  9. 如何在echarts地图默认的行政区(县)新增一个没有编号的区(如甘肃省天水市的区县新增一个新安区)
  10. 从贵价当道到平价之光,我们该如何看待全球智能穿戴市场之间的次元壁?