现代软件工程:计算器的制作

目标:戳我

  • 除了整数以外,还要支持真分数的四则运算。 (例如: 1/6 + 1/8 = 7/24)
  • 让程序能接受用户输入答案,并判定对错。 最后给出总共 对/错 的数量。
  • 逐步扩展功能和可以支持的表达式类型,最后希望能支持下面类型的题目 (最多 10 个运算符,括号的数量不限制):
    1. 25 - 3 * 4 - 2 / 2 + 89 = ?
    2. 1/2 + 1/3 - 1/4 = ?
    3. (5 - 4 ) * (3 +28) =?
  • 一次可以批量出 100 道以上的题目,保存在文本文件中, 并且保证题目不能重复,(1+2) 和 (2+1) 是重复的题目。 怎么保证题目不重复呢,请看详细题目要求

分析

题目要求有整数和分数的混合输入(不排除加上小数的混合输入),而且要求运算结果也需要为“真分数”的方式给出。好像没有现成的数据结构可以用,因此,这里先定义一个数据结构:Number

Number 成员变量:

  1. fenmu :分数的分母
  2. fenzi :分数的分子
  3. type :表示正负。当输入为小数时用来辅助操作

此外还包括一些基本的函数,比如分母分子的约分,分母是否为0,定义了Number的加减乘除操作,以及覆盖的toString方法等等。为了与正常四则运算的”/“区分,这里引入了一个”$”符号,来表述Number之间的除法运算。

都说代码=数据结构+算法,现在有了数据结构,接下来的工作就是找一个算法来解析四则运算公式了。这里我用到的是首尾扫描,把四则运算的字符串标准化,然后用栈来辅助计算的方法。

标准化

所谓标准化,就是把四则运算所在的字符串中的括号,小数点等不是数字,又不是运算符的字符。消除的方法是递归调用。

算法
  1. 如果输入的字符串str里面不包含任何的”(“,”)”以及”.”,那么可以直接计算。这里运算的优先级:$ 优先于 /,优先于 + - ;进栈出栈的基本方法:用一个变量保存当前扫描光标所在位置之前最近出现的符号o,扫描到数字,如果o为加减,减乘-1,加直接进栈;如果是乘除,则要取出栈顶元素然后跟当前元素进行乘除运算,进栈;加上$,需要多一个变量来保存$之前的操作符,原理是一样的,简单不过要复杂些,细心点就不会弄错了,比如$之前是 / ,这时候只需要栈顶元素乘以当前数字构成的Number,如果之前是,则直接相乘。
  2. 如果str中包含括号,先判断左右括号的数量以及出现的位置是否合法,如果合法则报错,提示用户重新输入;如果合法,把括号内部的内容拿出来带入第一步,得到一个Number,然后用Number的toString值替换括号出现的区域;
  3. 如果str中包含小数点。则扫描str,得到小数点前后的数,把这个数用Number表示出来,然后用此Number的toString方法替代掉小数点所在的区间,返回s;

有了后台的算法,做个图形化界面就不是难事儿了

  1. 可以用鼠标点击按钮来输入,也可以在输入框中直接键盘输入。
  2. 随机生成:默认是生成n个运算符,n在1~3之间,大小在10以内的n+1数
  3. 重置:清空输入和输出
  4. 计算:获得结果
  5. 目前的版本,随机输入还不能生成带括号的字符串..还没想到一个比较好的方法去去重,好像应该选树节点的方式来做的,那样子貌似可以方便去重。

先这样子…回寝室再写

2016年03月20日22:37:16