要求:设计一个算法,将一般算术表达式转化为逆波兰表达式,并求逆波兰表达式的值。

实现思路

  1. 获取一个中缀表达式
  2. 将表达式转换为后缀表达式
  3. 计算后缀表达式的结果

中缀表达式转换为后缀表达式的几个关键部分

假如不是运算符,则输出,否则进行下面步骤

  1. 假如遇到空栈或者‘(’时,直接入栈,并继续,因为第一个遇到的肯定是'#',所以直接入栈。
  2. 假如遇到'#',则说明表达式结束了,但得在前一点的后面进行判断。
  3. 假如遇到')',则进行出栈,知道遇到'(',并弹出,但不记录,因为我们不要括号的
  4. 优先级比较:
  • 假如优先级大于栈顶,则入栈
  • 小于或等于栈顶时,一直出栈,直到当前运算符优先级大于栈顶,则把当前运算符进栈。

计算后缀表达式

前一步已经将表达式存放在新的数组里面了,并且为了方便识别,在适当的位置都加了空格,方便识别。

由于需要进行计算,且要把char的数转换成一个整数,所以这里简单的利用一个整型数组,并且模拟栈的实现方式,基本思想如下:

  1. 对获取到后缀表达式进行扫描
  2. 如果为数字,则继续扫描直到遇到空格,并把数入栈。
  3. 假如为运算符,则进相应的运算,从栈中取出离栈顶最近的两个数,进行计算,并且把结果写在离栈顶较远的那个位置,并且把当前栈顶的数据清零。
  4. 最后获取到的结果会存放在数组的0位置。

结语

由于这个实验是我在学数据结构时的一个实验,刚学习编程,语言也比较混乱,如有错误的地方,欢迎指出。以下为代码部分:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
/*  (1)设计一个算法,将一般算术表达式转化为逆波兰表达式,并求逆波兰表达式的值。例如 #30*(40+20)/2-50#  #为两个界限符
*/
const int StackSize = 30;
char result[30];//接收转换结果,并添加空格
char num;//用来result数组的计数//定义一个栈结构体
typedef struct Stack
{char data[StackSize];int top;
}StackType;//出栈处理,输入:栈结构体
char Pop(StackType *p)
{char x;if(p->top == -1) {printf("under flow\n");exit(0);}x = p->data[p->top--];return x;
}
//入栈处理
void Push(StackType *p, char dat)
{if(p->top == StackSize -1){printf("over flow\n");exit(0);}p->data[++p->top] = dat;
}//为空时返回1,不为空则返回0
bool Emtry(StackType *p)
{if(p->top == -1)return 1;return 0;
}
//获取栈顶的数据
char GetTop(StackType *p)
{if(p->top != -1)return p->data[p->top];return 0;
}//判断是运算符还是运算对象bool isNumber(char op){switch(op){   case ' ':case '(':case ')':case '+':       case '-':     case '*':     case '/':case '#':      return 0;    default :       return 1;   }}
//获取运算符的优先级,1为最高,且统计优先级int priority(char ch){int value= 10; switch(ch){case '(':case ')':    value = 4; break;//当遇到左括号时,所有的符号都会进行入栈处理,直到遇到右括号,或者内部运算输出case '*':  value = 2; break;case '/':   value = 2; break;case '+':  value = 3;  break;case '-':  value = 3; break;case '#':   value = 5; break;default:  break;}return value;}/*
函数名:Nifix2Postfix
输  入:数组
返  回:无
功  能:将中缀表达式转换成后缀表达式并输出
*/
void Nifix2Postfix(char arr[])
{StackType* pStack = new StackType;pStack->top = -1;int i = 0;char ch;for(i=0;arr[i] != '\0';i++){if(isNumber(arr[i])){result[num++] = arr[i];}//不是对象时,即为运算符else{//首先判断是否为空,如果为空,则入栈if(Emtry(pStack) || arr[i] == '('){Push(pStack, arr[i]);continue;}if(arr[i] == '#')//结束符号break;if(arr[i] == ')')//出栈直到遇到({result[num++] = ' ';while((ch = Pop(pStack)) != '(' )//开始出栈,出到'('{result[num++] = ch;result[num++] = ' ';}continue;}result[num++] = ' ';//优先级比较ch = priority(GetTop(pStack)) - priority(arr[i]);//获取优先级比较后的结果,但ch>0时,运算符优先级大于栈顶,=0相等,<0小于//优先级大于栈顶if(ch > 0){//优先级大的入栈Push(pStack, arr[i]);}//优先级小于或等于栈顶else if(ch <= 0){//应该是出栈一个,然后判断优先级,假如不为空栈,继续判断优先级,然后将arr[i]入栈while( priority(arr[i]) >= priority(GetTop(pStack)))//此运算符优先级小于等于栈顶时,一直输出{
//                  printf("%c",ch = Pop(pStack));result[num++] = Pop(pStack);
//                  printf(" ");result[num++] = ' ';}Push(pStack, arr[i]);                           }}}while(GetTop(pStack) != '#'){result[num++] = ' ';result[num++] = Pop(pStack);}for(i=0;i<num;i++)printf("%c",result[i]);
}/*
函数功能:计算后缀表达式的值
输入:一个后缀表达式
输出:结果
*/
int Calculate(char arr[])
{int i, cal[10],top=-1;memset(cal,0,sizeof(cal));for(i=0;i<num;i++){if(isNumber(arr[i]))//判断是否是操作符,返回1不是,进来的只能是数字{//模拟入栈top++;while(arr[i] != ' ')//获取一个整数,并入栈{cal[top] = cal[top]*10 + arr[i++]-48;}}else{switch(arr[i]){//模拟出栈case '+':   cal[top-1] = cal[top-1] + cal[top]; cal[top--] = 0; break;case '-':    cal[top-1] = cal[top-1] - cal[top]; cal[top--] = 0; break;case '*': cal[top-1] = cal[top-1] * cal[top]; cal[top--] = 0; break;case '/': cal[top-1] = cal[top-1] / cal[top]; cal[top--] = 0; break;default: break;}}}return cal[0];
}int main(void)
{char  express[] = "#30*(40+20)/2-50#";//   gets(express);printf("中缀表达式:");printf("%s\n", express);printf("后缀表达式:");Nifix2Postfix(express);printf("\n");printf("运算结果为:%d\n", Calculate(result));return 0;
}

运行结果:

将一般算术表达式转化为逆波兰表达式,并求逆波兰表达式的值。相关推荐

  1. hdu 1394(树状数组求逆序数)

    解题思路:这道题是求循环数组中逆序数最小值,求逆序数这里肯定是用树状数组.只是这里有一点点变化,由于题目中n位数是0-n-1的一个排列,所以num[i]可表示为比num[i]小的数的个数.把第一位的数 ...

  2. 用不同的姿势求逆序对(复习篇)

    用不同的姿势求逆序对(复习篇) 文章目录 用不同的姿势求逆序对(复习篇) 前言 讲解 归并排序 树状数组 线段树 题目 思路 代码 归并排序求逆序对 树状数组求逆序对 线段树求逆序对 历届试题 小朋友 ...

  3. 多项式算法5:多项式求逆

    多项式算法5:多项式求逆 多项式求逆 前置知识: FFT NTT 多项式求逆 这里的多项式求逆,其实是求多项式的逆元. 对于多项式A(x)A(x)A(x),如果存在A(x)B(x)≡1(modxn)A ...

  4. 设计一个算法,将一般算术表达式转化为逆波兰表达式,并求逆波兰表达式的值

    栈的设计与使用 实验内容 设计一个算法,将一般算术表达式转化为逆波兰表达式,并求逆波兰表达的值 解题思路 (1)一般算术表达(中缀表达),如#3×(4+2)/2-5#,#为表达式界定符,逆波兰表达式( ...

  5. 255.0.0.0子网掩码相应的cidr前缀表示法是?_六十四、前缀,后缀,中缀表达式转化求值问题...

    「@Author:Runsen」 ❝ 编程的本质来源于算法,而算法的本质来源于数学,编程只不过将数学题进行代码化. 「---- Runsen」 ❞ 算法,一门既不容易入门,也不容易精通的学问. 上次介 ...

  6. 编译原理逆波兰式实验java_逆波兰式算法的编译原理实验过程.doc

    逆波兰式算法的编译原理实验过程 实验目的 深入理解算符优先分析法 掌握FirstVt和LastVt集合的求法有算符优先关系表的求法 掌握利用算符优先分析法完成中缀表达式到逆波兰式的转化 实验内容及要求 ...

  7. [数据结构考前必看]中缀表达式转化成后缀表达式_例题超多+分步骤讲解+带你手算

    中缀.后缀表达式定义 中缀表达式又称波兰式,有利于人们阅读与表达. 后缀表达式又称逆波兰式,有利于机器进行运算. 例题1: 中缀表达式:(a+b+c*d) /e 首先让我们来看一下运算符对应的优先级, ...

  8. 2015中缀表达式转化为后缀表达式(C++,附思路,注释多)

    这篇文章默认你已经知道转换的原理了,所以就不介绍如何转换了~如果不知道的话可以看这两篇文章,写得很好,可以看懂~ 详解如何将中缀表达式转化为后缀表达式_Dacyuan的学习笔记-CSDN博客_中缀算式 ...

  9. C语言编程对一个逆波兰式进行求值,算式与逆波兰式

    致憨憨的从前 当年,老师布置一道作业:编写一个计算器,要求输入算式,给出结果.算式中只包含+-*/^这几个运算符,算式中不含负数.由于是Python课程,我很快给出了解题方式,如下: while Tr ...

  10. 将中缀表达式转化为后缀表达式

    我们把平时所用的标准四则运算表达式,即"9+(3-1)*3+10/2"叫做中缀表达式.因为所有的运算符号都在两数字的中间,现在我们的问题就是中缀到后缀的转化. 中缀表达式" ...

最新文章

  1. 图片爬取数据解析数据持久化
  2. Sina App Engine 介绍
  3. java线程和操作系统线程_操作系统中的线程
  4. C++——容器小整理
  5. 137_Power BI 自定义矩阵复刻Beyondsoft Calendar
  6. oracle ora32771,Oracle的文件号、相对文件号及其他(续)
  7. GitLab CI/CD conda: command not found
  8. 知乎究竟走的是什么路线?克隆之路靠谱吗?
  9. android+获取图库图片+4.4,Android 从 Android 本地图库选择多个图片
  10. 电脑计算机稳定删除垃圾游戏,电脑卡怎么办简单步骤_如何清理电脑垃圾
  11. 大学生数学竞赛辅导:Stolz定理和f(x)≡0
  12. 基于微信公众号测试号进行微信授权登陆
  13. 【Android】仿淘宝商品详情页
  14. 爬虫之抽屉新热榜点赞基本示例
  15. 【leetcode刷题班】贪心题目求解
  16. wifidog 认证
  17. 一个碌碌无为的程序员
  18. 遥感图像场景分类方法总结
  19. C语言关系运算符详解
  20. 分销商城小程序开发解决方案

热门文章

  1. ACM解题总结——HihoCoder1199 (微软笔试题)
  2. 01-什么是网络爬虫
  3. FreeBSD 下玩 FC 游戏
  4. Selenium + C# 实现模拟百度贴吧签到 2
  5. Nature呼吁:应对21世纪的大规模流行病,各个学科必须联合起来
  6. android 地球仪源码,android OpenGL ES 地球仪绘制——球体绘制及纹理映射
  7. ar5b97无线网卡驱动linux 版下载,atheros ar5b97驱动
  8. windows 8 下五笔98版和新世纪版的解决方案
  9. 全国计算机二级vf成绩查询,2017全国计算机二级《VF》考点习题
  10. WIN10_用户获取最高的管理员权限(关闭UAC控制)