编译原理---四则运算表达式的计算简单实现
来源:互联网 发布:哪个批发软件最好用 编辑:程序博客网 时间:2024/05/01 21:10
博主从今天起正式开始了研究生的学习生活,下午在上到现代软件工程这门课的时候,老师留了个“大作业”让我们体会软件工程。。。说起来有点不好意思,博主虽然是某985高校软件学院的,但是感觉学校的教学水平。。。还是远比不上那几所知名的学校,甚至我觉得像杭州电子科技大学这样的有专长的学校,那样的培养机制(应该有很多人刷过杭电的acm吧),培养出的学生的编程能力反而更强。
书归正传,“大作业”的需求是给小学生写一个简单的四则运算表达式计算器。我一看,卧槽,大二自学android的时候写过一个类似的傻瓜APP啊,可惜当时不知道要将自己学到的知识进行整理和总结,也没有把源码留下来。不过好像老爸的手机里还有那个应用哈哈,当时还显摆呢。。。
其实四则运算的实现在大三学编译原理的时候专门有提到过啊,只不过时间一长就全还给老师了。上网搜实现的时候发现了这篇博客,和编译原理书上讲的实现思路一模一样。赶紧记下来以后留用。
-------------------------------------------------------原文分割--------------------------------------------------------------------------
本文实例讲述了java实现任意四则运算表达式求值算法。分享给大家供大家参考。具体分析如下:
该程序用于计算任意四则运算表达式。如 4 * ( 10 + 2 ) + 1 的结果应该为 49。
算法说明:
1. 首先定义运算符优先级。我们用一个map来保存优先级表
Map<String, Map<String, String>>
/** * 查表得到op1和op2的优先级 * @param op1 运算符1 * @param op2 运算符2 * @return ">", "<" 或 "=" */public String priority(String op1, String op2) { return priorityMap.get(op1).get(op2);}
2. 扫描表达式字符串,每次读入一个 token 进行处理。
使用两个辅助栈:optStack用于保存运算符,numStack用于保存操作数. 我们用 '#' 作为表达式的起始和结果标志符。
读入一个token,如果它是数字,则压入numStack栈中;
如果它是运算符,则取出optStack栈的栈顶元素A,将 A 与 token 进行优先级比较。
如果 A < token,则将 token 压入optStack栈。
如果 A = token,则说明 token和A是一对括号,此时将optStack栈的栈顶元素弹出。
如果 A > token,则从numStack中弹出2个操作数,从optStack中弹出1个运算符,并计算结果。
当optStrack栈为空时(即栈顶元素为 '#'),numStack栈的栈顶元素即为表达式的值。
算法实现:
/** * 算术表达式求值。 * 3 + 4 * 12 结果为51 * @author whf * */public class EvaluateExpression { // 运算符优先级关系表 private Map<String, Map<String, String>> priorityMap = new HashMap<String, Map<String, String>>(); private LinkedStack<String> optStack = new LinkedStack<String>(); // 运算符栈 private LinkedStack<Double> numStack = new LinkedStack<Double>(); // 操作数栈 /** * 计算表达式 * @param exp 四则运算表达式, 每个符号必须以空格分隔 * @return */ public double calcualte(String exp) { StringTokenizer st = new StringTokenizer(exp); while (st.hasMoreTokens()) { String token = st.nextToken(); process(token); } return numStack.pop(); } /** * 读入一个符号串。 * 如果是数字,则压入numStack * 如果是运算符,则将optStack栈顶元素与该运算符进行优先级比较 * 如果栈顶元素优先级低,则将运算符压入optStack栈,如果相同,则弹出左括号,如果高,则取出2个数字,取出一个运算符执行计算,然后将结果压入numStack栈中 * @param token */ private void process(String token) { while (false == "#".equals(optStack.getTop()) || false == token.equals("#")) { // token is numeric if (true == isNumber(token)) { numStack.push(Double.parseDouble(token)); break; // token is operator } else { String priority = priority(optStack.getTop(), token); if ("<".equals(priority)) { optStack.push(token); break; } else if ("=".equals(priority)) { optStack.pop(); break; } else { double res = calculate(optStack.pop(), numStack.pop(), numStack.pop()); numStack.push(res); } } } } /** * 执行四则运算 * @param opt * @param n1 * @param n2 * @return */ private double calculate(String opt, double n1, double n2) { if ("+".equals(opt)) { return n2 + n1; } else if ("-".equals(opt)) { return n2 - n1; } else if ("*".equals(opt)) { return n2 * n1; } else if ("/".equals(opt)) { return n2 / n1; } else { throw new RuntimeException("unsupported operator:" + opt); } } /** * 检查一个String是否为数字 * @param token * @return */ private boolean isNumber(String token) { int LEN = token.length(); for (int ix = 0 ; ix < LEN ; ++ix) { char ch = token.charAt(ix); // 跳过小数点 if (ch == '.') { continue; } if (false == isNumber(ch)) { return false; } } return true; } /** * 检查一个字符是否为数字 * @param ch * @return */ private boolean isNumber(char ch) { if (ch >= '0' && ch <= '9') { return true; } return false; } /** * 查表得到op1和op2的优先级 * @param op1 运算符1 * @param op2 运算符2 * @return ">", "<" 或 "=" */ public String priority(String op1, String op2) { return priorityMap.get(op1).get(op2); } /** * 构造方法,初始化优先级表 */ public EvaluateExpression() { // initialize stack optStack.push("#"); // initialize priority table // + Map<String, String> subMap = new HashMap<String, String>(); subMap.put("+", ">"); subMap.put("-", ">"); subMap.put("*", "<"); subMap.put("/", "<"); subMap.put("(", "<"); subMap.put(")", ">"); subMap.put("#", ">"); priorityMap.put("+", subMap); // - subMap = new HashMap<String, String>(); subMap.put("+", ">"); subMap.put("-", ">"); subMap.put("*", "<"); subMap.put("/", "<"); subMap.put("(", "<"); subMap.put(")", ">"); subMap.put("#", ">"); priorityMap.put("-", subMap); // * subMap = new HashMap<String, String>(); subMap.put("+", ">"); subMap.put("-", ">"); subMap.put("*", ">"); subMap.put("/", ">"); subMap.put("(", "<"); subMap.put(")", ">"); subMap.put("#", ">"); priorityMap.put("*", subMap); // / subMap = new HashMap<String, String>(); subMap.put("+", ">"); subMap.put("-", ">"); subMap.put("*", ">"); subMap.put("/", ">"); subMap.put("(", "<"); subMap.put(")", ">"); subMap.put("#", ">"); priorityMap.put("/", subMap); // ( subMap = new HashMap<String, String>(); subMap.put("+", "<"); subMap.put("-", "<"); subMap.put("*", "<"); subMap.put("/", "<"); subMap.put("(", "<"); subMap.put(")", "="); //subMap.put("#", ">"); priorityMap.put("(", subMap); // ) subMap = new HashMap<String, String>(); subMap.put("+", ">"); subMap.put("-", ">"); subMap.put("*", ">"); subMap.put("/", ">"); //subMap.put("(", "<"); subMap.put(")", ">"); subMap.put("#", ">"); priorityMap.put(")", subMap); // # subMap = new HashMap<String, String>(); subMap.put("+", "<"); subMap.put("-", "<"); subMap.put("*", "<"); subMap.put("/", "<"); subMap.put("(", "<"); //subMap.put(")", ">"); subMap.put("#", "="); priorityMap.put("#", subMap); }}
程序测试:
String exp = "4 * ( 10 + 2 ) + 1 #";EvaluateExpression ee = new EvaluateExpression();out.println(ee.calcualte(exp));
运行结果为 49。
希望本文所述对大家的C++程序设计有所帮助。
- 编译原理---四则运算表达式的计算简单实现
- 最简单的四则运算表达式计算
- 栈实现简单的四则运算表达式
- Java实现四则运算表达式计算
- C语言实现整数四则运算表达式的计算
- 数据结构之简单四则运算表达式求值8-(栈的实现)
- 输入一个只包含个位数字的简单四则运算表达式字符串,计算该表达式的值
- 计算一个字符串表示的四则运算表达式
- 表达式(四则运算)计算的算法
- 一个计算四则运算表达式文本的方法
- 计算带括号的四则运算表达式
- 表达式(四则运算)计算的算法
- 计算四则运算表达式
- 中缀计算四则运算表达式
- 后缀表达式计算四则运算
- 含括号和四则运算符的简单表达式的计算【c++ 50 lines】
- 用java实现计算String类型的四则运算——用栈和后缀表达式实现
- 计算带括号的四则运算表达式,这个实现方式你想过吗?
- JZOJ 3053. 旅行
- 2016.9.3 C组总结
- C++ 中 * 和 *& 的区别
- 第二周项目3--体验复杂度--汉诺塔
- 面向对象 创建对象的两种方式
- 编译原理---四则运算表达式的计算简单实现
- 汇编编译环境的建立
- C++构造函数简单实现电梯控制程序
- 第二周项目1--C/C++语言中函数参数传递的三种方式
- linq 一些基本语句
- python基础-导入模块
- Android 6.0 中TimePicker显示为滚动样式的方法
- 本地推送
- 信息采集