301
社区成员
发帖
与我相关
我的任务
分享





语法分析这一部分比较关键的是关于消除左递归,以及清晰的符号分类。比如对于一串等待分析的字符串,每一个符号或者括号都不是可以任意地进行化简的,每一个符号都有它所属的唯一的层次结构,比如表达式层、项层或因子层等等。
只要能够注意到这一点,语法分析就基本上清楚了,因为根据题目,输入数据并不是任意的数学表达式,其符号数量等格式都是固定的,因此语法分析并不难。
在第二次开发和第三次开发当中,加入了函数和函数调用这两部分。我的主要设计是函数表达式和待处理的表达式当作同等的表达式来看待,这样第二次作业的架构就能够有效地扩展到第三次架构。
在函数表达式的处理上,使用一个递归进行替换,遇到底层的自变量就相应返回其调用的值。
就是代码当中Polynomial和PolyTerm两个类。我把基本的式子化成了以下形式:
$$
Polynomial= \sum_{i=0}^{n} a_{i}\times x^{b_i} e^{c_i}
$$
其中$a_i$和$b_i$是整数,$c_i$是表达式。这个就是Polynomial类的基本形式。
$$
PolyTerm= a_{i}\times x^{b_i} e^{c_i}
$$
这是相应的PolyTerm的形式,也就是Polynomial的单体。其可以使用三元组表示:
$$
(a_i, b_i, c_i)
$$
对于不同的PolyTerm,使用toString作为关键字对其进行排序,并重写compareTo方法,这样就可以让java学会比较PolyTerm,然后就可以愉快地合并同类项了。Polynomial使用了TreeMap这一平衡树数据结构来储存有序的PolyTerm并指向其系数,非常方便。
在答案组成这一部分,我本来是废弃的,打算只通过语法分析器的化简直接得到很好的表达式,但是遇到了非常大的困难,也就是当基本的类类型过多的时候,项与项之间难以合并和化简,这使得代码的判断量陡增,同时可以预见的难以维护。尽管它在可扩展上相较于新设置答案组成的两个类有着更为优雅、更能够直接揭示数学本质的特点,但是难以在课程规定时间内得到一个比较好的设计,于是在纠结徘徊了很久还是因为ddl放弃了。
基于现有的设计,比如新增三角函数或者对数函数,可以继续通过答案组成当中的方式分析其基本不可化简的构成,然后使用多元组表示其不可化简的基本项。这样延续了非“无答案构成”的设想,语法分析器的工作被大大减轻,也算是取得了一点平衡吧。
对于我个人来说,心得体会最重要的是分析和设计整个程序的结构吧,这一部分也是耗时最多的部分,也重复返工了很多次代码。但是,在这一过程当中,也加深了我对于面向对象语言的理解,极大地提升了自己的能力。
总体上来说,第一单元的课程非常易于入手,目前来看很不错。