戏剧前奏——基本知识点

通常我们所看到的算术表达式,

程序代写官网请进入--》》http://www.xmsydw.com
网上淘宝代写请进入--》》http://apenny.taobao.com

运算符总是在两个操作数中间(除),如(A+B)*C,这样的表达式叫做中缀表达式。这种表达式不同的运算符优先级不同,而且通常含有括号,计算机很难理解这种表达式。在编译系统中,要把人易于理解的表达式翻译成能正确求值的机器指令。编译系统中对中缀形式的算术表达式的处理方式是: 先把中缀表达式转换成后缀表达式,再进行计算。

后缀表达式就是表达式中的运算符出现在操作数的后面,并且不含括号,如AB+C*。后缀表达式的特点:

(1).后缀表达式让操作数和中缀表达式的操作数先后次序相同,只是运算符的先后次序改变;

(2).后缀表达式没有括号,运算次序就是其执行次序。

在计算机内部,任何一个表达式都是由操作数、运算符和分界符组成。操作数和运算符是表达式的主要部分,分界符(如用#表示)标志了一个表达式的结束。我们把操作数、运算符和分界符称为表达式的单词

一个中缀表达式的四则运算规则:

1.先乘除后加减

2.先括号内后括号外

3.同级别时先左后右

下面以A+(B-C/D)*E为例对过程进行讲解。A+(B-C/D)*E转换成后缀表达式后为

ABCD/-E*+

其运算次序为:T1=CD/; T2=BT1-; T3=T2E*; T4=AT3+。

基于后缀表达式的两个特点,计算过程如下:计算时只要从左到右依次扫描后缀表达式的各个单词,当读到的单词为运算符时,就对该运算他会前两个操作数进施以此运算所代表的操作,然后将结果T插入到后缀表达式中再重复上面的操作。

享受过程——实现步骤和方法

根据以上的讲解,可初步地列出实现的步骤如下:

1.把中缀表达式的字符中提取出一系列表达式单词;

2.把中缀表达式单词系列转换成后缀表达式单词系列;

3.对后缀表达式词系列依次进行计算。

下面依次对各个步骤进行讲解。

把中缀表达式的字符中提取出一系列表达式单词

要提取表达式单词,首先要定义一个单词的类。该类要有两个属性:是否为操作数的标记;数据元素;

代码:

[java] view plaincopyprint?
  1. package cn.eddu.jxau.calculation;
  2. public class DataType {
  3. //是否为操作数
  4. private boolean isNum;
  5. //数据元素
  6. private Object data;
  7. public DataType() {
  8. isNum = false;
  9. data = null;
  10. }
  11. public DataType(boolean isNum, Object data) {
  12. this.isNum = isNum;
  13. this.data = data;
  14. }
  15. //get和set方法
  16. //......
  17. }

将算式表达式转换成操作数和运算符,放入队列中

代码:

[java] view plaincopyprint?
  1. private static void splitExpress(String str, String... regexs) {
  2. StringBuilder strBuilder = new StringBuilder();
  3. for (int i = 0; i < regexs.length; i++) {
  4. if (i == regexs.length - 1) {
  5. strBuilder.append("[").append(regexs[i]).append("]");
  6. } else {
  7. strBuilder.append("[").append(regexs[i]).append("]|");
  8. }
  9. }
  10. Pattern p = Pattern.compile(strBuilder.toString());
  11. Matcher m = p.matcher(str);
  12. List<String> strList = new ArrayList();
  13. int strStart = 0; // 分割单词的首位置
  14. String s; // 分割的单词
  15. Double d;
  16. while (m.find()) {
  17. s = str.substring(strStart, m.start()).trim();
  18. if (!s.equals(new String())) {
  19. d = Double.parseDouble(s);
  20. pressQ.push(new DataType(true, d));
  21. }
  22. strStart = m.end();
  23. s = str.substring(m.start(), m.end());
  24. pressQ.push(new DataType(false, s));
  25. }
  26. s = str.substring(strStart, str.length()).trim();
  27. if (!s.equals(new String())) {
  28. d = Double.parseDouble(s);
  29. pressQ.push(new DataType(true, d));
  30. }
  31. }

把中缀表达式单词系列转换成后缀表达式单词系列

中缀表达式转换成后缀表达式的算法步骤:(1).设置一个堆栈S,初始时将栈顶元素设置为#。(2).顺序读入中缀表达式,当读到的单词为操作数时将其加入到线性表L, 并接着读下一个单词。(3).令x1为当前栈顶运算符的变量,x2为当前扫描读到的运算符的变量,当顺序从中缀表达式中读入的单词为运算符时就赋予x2;然后比较x1与x2的优先级,若优先级x1>x2,将x1从S中出栈,并加入L中,接着比较新的栈顶运算符x1与x2的优先级;若优先级x1<x2,将x2入栈S,接着读下一个单词;若优先级x1=x2且x1为”(”而x2为”)”,将x1出栈,接着读下一个单词;若优先级x1=x2且x1为”#”而x2为”#”,算法结束。

各运算符优先级关系表

x2

x1

+

-

×

÷

(

)

#

+

>

>

<

<

<

>

>

-

>

>

<

<

<

>

>

×

>

>

>

>

<

>

>

÷

>

>

>

>

<

>

>

(

<

<

<

<

<

=

$

)

>

>

>

>

$

>

>

#

<

<

<

<

<

$

=

表中x1为+或-,x2为*或/时,优先级x1<x2,满足中缀表达式规则1.先乘除后加减;x1为+、-、*或/,x2为(或/时,优先级x1<x2,满足中缀表达式规则2.先括号内后括号外;当x1的运算符x2的运算符同级别时,优先级x1=x2,满足中缀表达式规则3.同级别时先左后右。出现表中的$表示中缀表达式语法出错。

中缀表达式转换成后缀的过程

步骤

中序表达式

堆栈

输出

1

A+(B-C/D)*E#

#

 

2

+(B-C/D)*E#

#

A

3

(B-C/D)*E#

#+

A

4

B-C/D)*E#

#+(

A

5

-C/D)*E#

#+(

AB

6

C/D)*E#

#+(-

AB

7

/D)*E#

#+(-

ABC

8

D)*E#

#+(-/

ABC

9

)*E#

#+(-/

ABCD

10

*E#

#+(-

ABCD/

11

*E#

#+(

ABCD-

12

*E#

#+

ABCD-

13

E#

#+*

ABCD-

14

#

#+*

ABCD-E

15

#

#+

ABCD-E*

16

#

#

ABCD-E*+

代码:

[java] view plaincopyprint?

http:apenny.taobao.com

  1. /**
  2. * 将队列中的操作数和运算符转换成后缀表达式
  3. * @return
  4. */
  5. private static void toPostfix() {
  6. sigStack.push("#");
  7. pressQ.push(new DataType(false, "#"));
  8. String topSign = null;
  9. DataType datatype = null;
  10. String sign = null;
  11. while(!sigStack.isEmpty() && !pressQ.isEmpty()) {
  12. topSign = (String)sigStack.peek();
  13. datatype = (DataType)pressQ.peek();
  14. if(datatype.isNum()) {  //取出的是操作数
  15. suffixL.add(datatype);
  16. pressQ.pop();
  17. } else {                //取出的是运算符
  18. sign = (String)datatype.getData();
  19. if(sign.matches("[\\+\\-\\*[/()#$]]{1}")) {
  20. if(">".equals(signMap.getValue(topSign, sign))) {
  21. suffixL.add(new DataType(false, sigStack.pop()));
  22. } else if("<".equals(signMap.getValue(topSign, sign))) {
  23. sigStack.push(sign);
  24. pressQ.pop();
  25. } /*else if("=".equals(signMap.getValue(topSign, sign)) && topSign.equals("(") && sign.equals(")")) {
  26. sigStack.pop();
  27. pressQ.pop();
  28. } */else if("=".equals(signMap.getValue(topSign, sign))&& topSign.equals("#")) {
  29. break;
  30. } else if(sign.equals(")")) {
  31. if("=".equals(signMap.getValue(topSign, sign)) && topSign.equals("(")) {
  32. sigStack.pop();
  33. pressQ.pop();
  34. } else {
  35. while(">".equals(signMap.getValue(topSign, sign))) {
  36. suffixL.add(new DataType(false, sigStack.pop()));
  37. topSign = (String)sigStack.peek();
  38. }
  39. }
  40. } else {
  41. try {
  42. throw new Exception("算术表达式错误!");
  43. } catch (Exception e) {
  44. e.printStackTrace();
  45. }
  46. }
  47. }
  48. }
  49. }
  50. }

对后缀表达式词系列依次进行计算。

计算时只要从左到右依次扫描后缀表达式的各个单词,当读到的单词为运算符时,就对该运算他会前两个操作数进施以此运算所代表的操作,然后将结果T插入到后缀表达式中再重复上面的操作。

代码:

[java] view plaincopyprint?
  1. DataType e = null;
  2. double d1, d2, d;
  3. d1 = d2 = d =0;
  4. int i = 0;
  5. while(!suffixL.isEmpty() && i < suffixL.size()) {
  6. e = suffixL.get(i);
  7. if(!e.isNum()) {
  8. String sign = (String)e.getData();
  9. d1 = (Double)suffixL.get(i-2).getData();
  10. d2 = (Double)suffixL.get(i-1).getData();
  11. if("+".equals(sign)) {
  12. d = d1+d2;
  13. } else if("-".equals(sign)) {
  14. d = d1-d2;
  15. } else if("*".equals(sign)) {
  16. d = d1*d2;
  17. } else if("/".equals(sign)) {
  18. d = d1/d2;
  19. } else {
  20. try {
  21. throw new Exception("表达式出错!");
  22. } catch (Exception e1) {
  23. // TODO Auto-generated catch block
  24. e1.printStackTrace();
  25. }
  26. }
  27. suffixL.remove(i-2);
  28. suffixL.remove(i-2);
  29. suffixL.set(i-2, new DataType(true, d));
  30. i = i-2;
  31. }
  32. i++;

见证奇迹——实例测试

测试代码:
[java] view plaincopyprint?
  1. package cn.eddu.jxau.calculation;
  2. public class Test {
  3. /**
  4. * @param args
  5. */
  6. public static void main(String[] args) {
  7. System.out.println(Calculation.calculate("(4-4/7)*7"));//"12+(40-6/3)*4"   (6+4)*5
  8. System.out.println((4-4/7)*7);
  9. }
  10. }

结果:

 
24.0
28
 
可以发现通过转换成后缀表达式后的计算比较直接的写计算式不要准确,直接表达式会将一步计算的结果转化成int类型的数后再进行计算。

转载于:https://www.cnblogs.com/sourcecode2014/p/3288542.html

表达式(四则运算)计算的算法代写 essay代写相关推荐

  1. [基础算法]通过后缀表达式实现表达式的计算

    要求说明: (1)从键盘接收算术表达式,以"#"表示接收结束: (2)输出算术表达式的值: (3)操作数仅限于非负整数,操作符只能是+.-.*./.^.(.) (4)可以判断表达式 ...

  2. C语言表达式的求解规则,C语言实现整数四则运算表达式的计算

    一.问题重述 [问题描述] 从标准输入中读入一个整数算术运算表达式,如5 - 1 * 2 * 3 + 12 / 2 / 2  = .计算表达式结果,并输出. 要求: 1.表达式运算符只有+.-.*./ ...

  3. 数据结构与算法——中缀转后缀表达式以及计算

    中缀表达式转后缀表达式 思路分析: 初始化两个栈:运算符栈s1 和储存中间结果的栈s2 从左至右扫描中缀表达式 遇到操作数,将其压入s2 遇到运算符时,比较其与s1 栈顶运算符的优先级 如果s1 为空 ...

  4. python算法——字符串表达式的计算

    preface:最近有个面试,被要求给出一个字符串表达式,计算出结果.本以为是见到过的,想着用一个栈,然后被面试官打断说你这样是有问题的,然后想了说用树,又被打断说是有问题的,再仔细想想.结果还是没整 ...

  5. java中缀表达式转后缀表达式(逆波兰算法)

    四则运算是栈的重要应用之一 中缀表达式转后缀表达式(逆波兰算法)过程 从左到右遍历中缀表达式 数字直接输出为后缀表达式一部分 如果是符号,则判断与栈顶元素的优先级 高于栈顶元素优先级直接入栈 低于或等 ...

  6. Java堆栈的应用2----------中缀表达式转为后缀表达式的计算Java实现

    1.堆栈-Stack 堆栈(也简称作栈)是一种特殊的线性表,堆栈的数据元素以及数据元素间的逻辑关系和线性表完全相同,其差别是线性表允许在任意位置进行插入和删除操作,而堆栈只允许在固定一端进行插入和删除 ...

  7. 栈应用(中缀表达式转后缀表达式并计算后缀表达式的值)

    [0]README 0.1) 本文旨在总结 中缀表达式转后缀表达式并计算后缀表达式的值 的步骤,并给出源代码实现: 0.2) 本文中涉及到的源代码均为原创,是对中缀转后缀和计算后缀的简单实现,(旨在理 ...

  8. 16.算法调用优先于手写的循环

    STL算法涉及面很广,这意味着你本该编写循环来完成的任务也可以用STL算法来完成. 例如,有一个Widget类: class Widget { public:...void redraw() cons ...

  9. mysql .pdb是什么文件_计算广告算法到底要做什么?

    这个话题在这个专栏开篇就该去讲.恰逢今天公司业务和财务培训(20190216)之后,也有一些思索,索性就都汇总写下来.本文杂述,不尽完备,但是值得不断完善. 我喜欢一句话"革命不是请客吃饭, ...

  10. heap c语言数组实现,垃圾回收算法实现之 - 分代回收(完整可运行C语言代码)...

    分代垃圾回收(Mark-Sweep GC),并不是一个具体的算法,只是结合了几种垃圾回收算法,把对象按特点进行了分类,对每种特点的对象集执行不同的回收算法,从而提升回收效率 阅读本文之前,你最好已经了 ...

最新文章

  1. Linux redis安装教程,Linux 下redis5.0.0安装教程详解
  2. Environment.CurrentDirectory 的一个坑
  3. 普通计算机硬件,将普通显示器更改为触摸屏_计算机硬件和网络_IT /计算机_数据...
  4. linux文件属性和类型
  5. 腾讯云对象存储 python_GitHub - fushall1104/cos-python3-sdk: 腾讯云对象存储服务(cos)Python3.5版本SDK...
  6. mysql decimal 上限_关于mysql的decimal类型的外键的一个特殊限制
  7. c++ opencv [ INFO:0] global c:\build\master_winpack-build-win64-vc15\***
  8. java 计算限行尾号(北京)
  9. 软件开发文档的编写---软件研制任务书 (2015-03-14 17:55:03)转载▼ 标签: 软件 文档 任务书 需求 要求 分类: 软件过程改进 一. 简介 客户要
  10. 食堂点餐小程序,智慧食堂小程序,食堂预约点餐小程序毕设作品
  11. 自定义vscode插件路径及离线安装VSIX说明
  12. Python爬虫:网易云音乐评论爬取
  13. 《学习总章》硬件工程师学习首页
  14. 【opencv】鱼眼图像畸变校正——透视变换
  15. 2018小米春招,擦黑板
  16. java jframe 图片_java中JFrame添加背景图片
  17. 深度学习中的优化函数optimizer SGD Adam AdaGrad RMSProp
  18. 如何入门数字IC验证工程师,需要具备哪些知识和能力?培训班速成是否可行?
  19. 如何以管理员的身份运行命令提示符cmd
  20. 2012年总结2013年展望

热门文章

  1. Docker官方文档学习笔记(二):Docker Desktop入门
  2. 开源中国众包平台派活:微信小程序任务
  3. 【Python】爬取2019年男篮世界杯数据,并可视化
  4. linux polkitd 漏洞,Ubuntu Linux中的特权提升漏洞Dirty Sock分析(含PoC)
  5. [Android 测试] 性能回归测试之 MonkeyRunner使用、插件扩展、结合批处理
  6. 1179: 带参宏定义(函数专题)
  7. “拼多多”被薅的问题出在哪儿?损失将如何买单?
  8. linux温度软件,linux-查看cpu温度的方法
  9. 马氏距离 java实现_Python怎么实现马氏距离
  10. 520,张一鸣宣布卸任字节跳动CEO!