1.实验内容
一元稀疏多项式计算器
使用语言:Java 语言
编译环境:openJDk-1.8
2.问题描述
设计一个简易的一元稀疏多项式计算器。
3.需求分析
经过分析,本系统需完成的主要功能如下:
- 通过图形化界面点击按钮输入或键盘输入多项式
- 通过输入限制确保符合一元稀疏多项式的格式
- 通过按钮组选择输出结果:多项式计算结果、在某点的值、多项式的导数(扩展功能)
- 多项式的计算功能
- 多项式的求值功能
- 多项式的求导功能
4.概要设计
-=ADT=-
{
void do_bracket_event (String ss); //括号输入操作
void do_mark_event (String ss); //运算符输入操作
void do_backspace_event (String ss); //删除操作
void do_number_event (String ss); //数值输入操作
void do_ decimalPoint_event (String ss); //小数点输入操作
void do_ equals_event (String ss); //运算输出操作
void do_ clear_event (String ss); //清空重置操作
Boolean resultPreOperate(); //运算输出前置操作
void derivation(); //导数运算
void value(); //数值运算
void Polynomial(); //多项式运算
}
5.存储结构
通过 ArrayList<ArrayList> 和 TreeMap<Double, Double> 存储
ArrayList<ArrayList>外层存储整个多项计算式中的每个一级多项式
内层 ArrayList 存储每个一级多项式中的每项
TreeMap 进行运算过程,将每一项的指数作为 Key,相同指数的系数加和作为对应的 Value
6.算法流程图
7.算法时间复杂度分析
本程序主要以操作 treeMap 为主,故时间复杂度为 O(logn)
8.调试分析
本程序主要的操作对象是 ArrayList 与 TreeMap,最重要的操作是输入限制和字符串切割,这是本程序中的重点,是此程序可能出现问题的主要原因之一:
【问题一】
现象:输入计算式在检测加入 ArrayList 时出现错误。
原因:程序期待的输入内容应为 aX^b(其中 a 为系数 b 为指数)但实际输入过程中会有所省略。例如在指数为 1 的时候会省略 ^b,在指数为 0 的时候(即该项为常数项时)会省略 X^b,所以在实际运行过程中应加入相应的分支判断来保证省略写法依旧能代表完整意义加入到存储结构中,且在输出过程中也应该进行相应的输出优化以符合日常用户阅读书写逻辑,例如当系数和指数为整数时不再显示小数点及其后面的 0,当系数为 1 或-1 的时候省略掉系数中的数字,当该项为常数项时只显示数字,当该项的指数为 1 时不显示指数,前面没有其他项的时候加号不再显示,计算后系数为 0 的项不再显示,当所有项系数均为 0 的时候最后结果显示为 0。
【问题二】
现象:ArrayList 加载到 TreeMap 时出现错误。
原因:输入限制限制不全面。应严格限制输入规范,如加减号不应连续贴合出现,每一项中应只出现一个 X,每一项中只能出现一个 ^,结果输入框中只有在 ^ 后面才能添加-,小数点的数量应该严格规范不应在系数或指数部分出现多个小数点导致数值录入失败。
【问题三】
现象:结果输出指数项为正序。
原因:比较器自然排序默认从小到大。在实例化 TreeMap 的同时传入逆序的比较器(o1, o2) -> -Double.compare(o1, o2)。
【问题四】
现象:结果输出文本框中从右开始会使部分字符顺序出现问题,如 “^” “-”。
原因:JavaFx 原生问题。设置右对齐替换文本从右开始,尝试使用 CSS 样式进行控制发现 JavaFx 的 TextField 并不能很好的适配 CSS 的文本右对齐,最终在 FXML 文件中设置 alignment=“CENTER_RIGHT” 和 nodeOrientation="LEFT_TO_RIGHT"完成右对齐操作并不出现视觉错误。