├── README.md ├── hw1 ├── Expr.java ├── Factor.java ├── Lexer.java ├── MainClass.java ├── Number.java ├── Parser.java ├── Term.java └── Variable.java ├── hw2 ├── Cos.java ├── Expr.java ├── Factor.java ├── Lexer.java ├── MainClass.java ├── Number.java ├── Parser.java ├── SelfDefine.java ├── Sin.java ├── StringSimplify.java ├── Term.java └── Variable.java └── hw3 ├── Cos.java ├── DeCos.java ├── DeSin.java ├── DeVariable.java ├── Derivative.java ├── Expr.java ├── Factor.java ├── Lexer.java ├── MainClass.java ├── Number.java ├── Parser.java ├── SelfDefine.java ├── Sin.java ├── StringSimplify.java ├── Term.java └── Variable.java /README.md: -------------------------------------------------------------------------------- 1 | # 本仓库包含OO四个单元作业及上机内容,分别位于不同分支中,请切换分支查看! 2 | # OO第一单元总结 3 | 4 | --- 5 | ## 前言 6 | 7 | 在经历了第一单元三次作业的(~~蹂躏~~)磨练之后,笔者终于从一个OO和Java的**小白**晋升为**萌新**了。回想起自己第一周开始做作业时由于缺乏Java的基础知识而一连几天毫无进展,最后连续鏖战将近二十个小时才勉强完成任务时的狼狈的样子,不免有一种 “忆往昔峥嵘岁月稠”的感觉,令人心中百感交集。 8 | 9 | ~~好了,不说废话了()~~ 10 | 11 | 接下来,笔者将对自己第一单元三次作业进行一个较为全面的复盘,分别对三次作业的架构、代码的复杂度、类间关系、强测和互测反映出来的bug等进行总结和分析。 12 | 13 | ## 一、Homework1 14 | 15 | * ### 架构思路 16 | 17 | 对于第一次作业的架构笔者思考了整整两天,不可谓不折磨~~(其实主要是因为不懂Java,hhhh)~~,最终笔者决定第一次课上实验时课程组所给的advance例程中的架构,也就是主流的递归下降方式。该架构的主要思想是对输入的表达式抽象化、层次化,将其抽象为表达式、项、因子三个层次,表达式由项组成,项则由因子组成,在处理时通过递归的方式逐层深入处理,处理到因子层次时,根据所遇因子的不同种类选择不同的解析方法,解析后返回因子,本次递归结束。 18 | 19 | 这一架构相对于字符串解析的方式具有很大优势。第一大优势就在于其容错性和可读性较高,我们可以很清楚地看到每一层的行为,遇到程序出错时也比较好定位到出错的具体层级和方法。与此同时,这种架构不容易出现细节性的bug~~(理论上是这样的)~~,可以有效避免很多不容易测出来的小问题(比如采用字符串解析时需要考虑到符号的顺序等各种细节,而递归下降实际将很多东西交由程序自动处理)。第二大优势则在于代码可扩展性很强,这一点在后两次作业中展现得尤其明显。新增加的很多要求,大多都可以通过增加Factor因子种类的方式来解决。并且类似于嵌套括号的问题,甚至不需要进行额外的考虑,架构本身就已经将嵌套括号的情况囊括其中。 20 | 21 | * ### 类间关系 22 | 23 | ![hw1](https://alist.sanyue.site/d/imgbed/202311252242136.png) 24 | 25 | 如图所示,本次作业主要移位器**Lexer**和解析器**Parser**组成解释模块,并且将表达式抽象为**Expr**、**Term**和**Factor**三个层次,其中**Factor**为接口,在本次作业中**Expr**、**Term**、**Variable**和**Number**四个类实现了该接口。 26 | 27 | * ### 代码复杂度分析 28 | 29 | **Statistic** 30 | 31 | ### ![image-20230317195055986](https://alist.sanyue.site/d/imgbed/202311252242678.png) 32 | 33 | **Method metrics** 34 | 35 | ![image-20230317195630114](https://alist.sanyue.site/d/imgbed/202311252242778.png) 36 | 37 | ![image-20230317195737321](https://alist.sanyue.site/d/imgbed/202311252242039.png) 38 | 39 | **Class Metrics**![image-20230317195823422](https://alist.sanyue.site/d/imgbed/202311252242963.png) 40 | 41 | 在方法复杂度分析中可以看到,Expr的merge、simplify,Parser的parseTerm和Term的orgnizeFactor这几个方法的复杂度都比较高,因为这几个方法中实现了太多的功能,并且没能很好地将其中的某些部分提炼为单独的方法,导致这几个方法较为臃肿。 42 | 43 | 在类复杂度分析中可以看出Expr、MainClass、Parser和Term的复杂度都比较高,这也是因为这几个类中实现的方法较多,例如在MainClass中不仅实现了函数入口main,还实现了对表达式进行预处理等功能。 44 | 45 | * ### bug分析 46 | 47 | 第一次作业写完之后没有出现什么严重的bug,强测也得到了较为不错的成绩,而互测中唯一被hack成功的bug是因为超时导致的,这一bug的原因是我在进行最后的长度优化时,为了将式子第一项变成正数采用了太多次循环导致的,这一点也是我设计过程中出现的疏漏,修改了这一部分循环之后也成功通过了互测样例。 48 | 49 | ## 二、Homework2 50 | 51 | * ### 架构思路 52 | 53 | 第二次作业在第一次作业的基础上增加了嵌套括号的支持以及自定义函数、三角函数两类因子,也是一次相当复杂的迭代。前文笔者提到过,递归下降的架构具有很好的可扩展性,这一点在这次迭代中便展现得淋漓尽致。首先是嵌套括号的支持,第一次作业的架构已经很好地帮我们实现了~~(乐)~~。其次是自定义函数和三角函数这两类因子,我们本质上只是再多设计两个实现**Factor**接口的类罢了。很美好对吧? 54 | 55 | hhh,但是说来简单做起来难。在实现自定义函数的过程中,笔者新定义了**SelfDefine**类用于实现自定义函数定义式的解析以及处理,在解析表达式时若遇到自定义函数,便直接开始对自定义函数处理后的表达式进行解析,这本质是另外一套解析表达式的方案,即遇到相关的变量便将传入的参数返回作为因子,处理完后再将整个表达式作为表达式因子返回。在三角函数处理的过程中,我们只需要将三角函数括号内部分作为表达式进行解析,之后加上三角函数名返回即可,相对于自定义函数较为简单一些。 56 | 57 | _但是!但是!!但是!!!_ 58 | 59 | ~~三角函数的化简却是我一生之痛。~~三角函数的化简还是颇有难度的,笔者在这部分仅仅处理了sin^2+cos^2=1这部分就花了整整两天时间,并且还只能做到半成品。对这部分的化简,我的大致思路是将平方项取出存入ArrayList中,然后将这一项的Hashmap整个存入另一个ArrayList的相同位置中,之后每次出现平方项就遍历存储平方项的ArrayList,如果有匹配的平方项再比较其系数是否一致,若一致则可进行消除操作,改变对应项的Hashmap以及相应系数。 60 | 61 | * ### 类间关系 62 | 63 | ![hw2](https://alist.sanyue.site/d/imgbed/202311252242054.png) 64 | 65 | 从类图中我们可以看到,这次作业的架构比上次复杂了不少,主要是由于新增了两个因子导致的。Expr内部方法的显著增多一方面是由于化简三角函数时使用了大量方法,另一方面时笔者对第一次作业的架构进行了优化,将一些原有的代码抽象成了新的方法,提高了代码的可读性和可维护性。 66 | 67 | * ### 代码复杂度分析 68 | 69 | **Statistic** 70 | 71 | ![image-20230317205825236](https://alist.sanyue.site/d/imgbed/202311252242003.png) 72 | 73 | 我们可以看到,代码的总行数达到了809行,基本是第一次作业的两倍,可见这次迭代的量还是很大的。 74 | 75 | **Method metrics** 76 | 77 | ![image-20230317210033870](https://alist.sanyue.site/d/imgbed/202311252242685.png) 78 | 79 | ![image-20230317210059711](https://alist.sanyue.site/d/imgbed/202311252242474.png) 80 | 81 | ![image-20230317210123536](https://alist.sanyue.site/d/imgbed/202311252242437.png) 82 | 83 | 从图中可以看出,除了第一次作业出现的复杂度较高的方法外,Expr的TriMatchPro方法也非常高,而该方法复杂度较高的原因是它作为三角函数化简最重要的方法,多次调用了其他方法,并且自身存在递归调用。 84 | 85 | **Class Metric** 86 | 87 | ![image-20230317211628874](https://alist.sanyue.site/d/imgbed/202311252242120.png) 88 | 89 | 从中我们看到,**SelfDefine**作为新增的自定义函数类,其复杂度也是达到了较高的水准,这是因为其中不仅实现了函数表达式的解析,还实现了参数处理,函数调用处理等一系列方法。 90 | 91 | * ### bug分析 92 | 93 | 本次作业的bug还是比较惨痛的,笔者由于花了太多的时间对三角函数进行化简,导致没能对基础的功能进行充分的测试,使得一个很大的漏洞没有被发现,强测最终只拿到了很低的分数,互测也被狠狠地hack了(悲)。 94 | 95 | 这次作业的bug其实也不是很隐蔽,因为我在返回三角函数因子时将其内部的表达式化为了最简形式,也就代表着^被重新变成了**,而在Term中进行合并时又进行了一次因子的解析,这就导致再次解析到幂次时他不认识了,抛出了异常。 96 | 97 | 总体来说,这个bug并不难发现,完全是没有充分测试造成的。其次,这个bug也与架构有一定的关系,说明我的架构还不是很简洁,出现了冗余的调用和重复的操作。 98 | 99 | ## 三、Homework3 100 | 101 | * ### 架构分析 102 | 103 | 本次作业新增内容不多,仅仅增加了一个求导因子以及自定义函数的嵌套调用。这里笔者就不得不再提一下递归下降架构的优越性,因为对于递归下降架构而言,自定义函数的嵌套调用已经实现了~~(对!就是已经实现了hhh)~~。所以我们只用集中火力攻克求导因子的问题就可以了。 104 | 105 | 其实笔者这次作业做的并不算顺利,因为开始并没有将递归下降的精髓移植到求导上来,一心想要通过字符串解析的方式进行求导运算,导致笔者很长时间都非常痛苦,写了好几百行自己都不愿意去看的求导代码,并且后面还有很大一部分尚未完成。于是笔者最终还是选择放弃了字符串解析的方法,将递归下降的方法照猫画虎地应用在了求导上面,只是最后解析因子时返回值变为导数,然后在Term中处理时对项应用乘法法则,将一个表达式整体返回。结果这种架构果然不负所望,很容易就完成了之前几百行代码也没能完成的工作,并且结构非常的清晰。 106 | 107 | * ### 类间关系 108 | 109 | ![hw3](https://alist.sanyue.site/d/imgbed/202311252242510.png) 110 | 111 | 从图中可以看出,由于增加了求导因子,导致类图又~~“凌乱”~~了许多。但是仔细观察我们还是能够看出来,主要增加的内容就是**DeSin**、**DeCos**、**DeVariable**、**Derivative**等求导因子。 112 | 113 | * ### 代码复杂度分析 114 | 115 | **Statistic** 116 | 117 | ![image-20230317215801020](https://alist.sanyue.site/d/imgbed/202311252242867.png) 118 | 119 | 从图中可以看出,这次作业的代码行数来到了1376行,相比上次又增加了将近600行。emmm,习惯了。 120 | 121 | **Method Metric** 122 | 123 | ![image-20230317220130466](https://alist.sanyue.site/d/imgbed/202311252242167.png) 124 | 125 | ![image-20230317220207112](https://alist.sanyue.site/d/imgbed/202311252242515.png) 126 | 127 | ![image-20230317220226648](https://alist.sanyue.site/d/imgbed/202311252242306.png) 128 | 129 | ![image-20230317220243025](https://alist.sanyue.site/d/imgbed/202311252242570.png) 130 | 131 | 这次的方法复杂度分析,最直观的就是方法的总数有了明显的提升,一个原因是本次求导新增了不少方法,另一个原因是笔者对之前的代码再次进行了优化,提炼了更多的方法,提高了代码的可读性。所以我们可以看到,几个之前复杂度较高的方法的复杂度都降了一半以上。并且可以看出,有多个方法耦合度较高,说明方法之间联系过于紧密。 132 | 133 | **Class Metric**![image-20230317220608916](https://alist.sanyue.site/d/imgbed/202311252243318.png) 134 | 135 | 从该图可以看到,新增的类没有出现复杂度过高的情况。 136 | 137 | * ### bug分析 138 | 139 | 本次作业较为顺利,除了在自己测试时测出了dz不能求导这种睿智的bug之外,在强测中没有发现其他的bug,但是互测被hack了3刀,均是因为没有考虑到当自定义函数代价过高时会超时和超内存的问题。修改的方法也是将自定义函数的解析放到**调用时**进行。 140 | 141 | ## 四、心得体会 142 | 143 | 第一单元作业可谓是完成的历经坎坷,让笔者从假期的安逸状态最快速度地进入到了高度紧张的学习状态,并且在短短几天内熟悉了Java的基本语法和IDEA的基本操作,虽说是过程比较心酸,但是收获确实颇丰,而且这段经历必定会深深地烙印在笔者的心里。 144 | 145 | 从第一单元的作业中,我明白了一个良好的架构的重要性,因为开始选择了正确的架构,所以第二次作业的迭代没有出现太大范围的重构,但是第三次作业错误架构的选择也让我一定程度上尝到了重构的苦头。以后进行工程开发时,首先应该对架构有一个明确的认识和规划,然后再进行操作,这样可以最大程度地避免大范围重构的可能,并且提高代码的可维护性和可扩展性。 146 | 147 | 除此之外,我还悟出了一些bug测试的方法。首先就是逐渐缩小出现bug的样例,找到稳定复现bug的部分,分析出其中与其他样例不同的地方,然后回到代码中找这部分地方对应的代码段,并通过调试找出漏洞。其次就是应该多测试一些边缘化的数据,例如第一次和第三次互测中tle的数据均为cost边缘的数据,由此可见边缘化的测试非常重要。 148 | 149 | 希望在接下来的OO旅程中,我能汲取这个单元的作业和教训,学到更多的知识和技能,取得更好的成绩。 150 | -------------------------------------------------------------------------------- /hw1/Expr.java: -------------------------------------------------------------------------------- 1 | import java.math.BigInteger; 2 | import java.util.ArrayList; 3 | import java.util.Collections; 4 | import java.util.HashMap; 5 | import java.util.Iterator; 6 | 7 | public class Expr implements Factor { 8 | private final ArrayList terms; 9 | 10 | public Expr() { 11 | this.terms = new ArrayList<>(); 12 | } 13 | 14 | public void addTerm(Term term) { 15 | this.terms.add(term); 16 | } 17 | 18 | public void simplify(Expr expr) { 19 | String exp = expr.toString(); 20 | ArrayList term = new ArrayList<>(); 21 | Collections.addAll(term, exp.split("\\+")); 22 | HashMap finalexp = new HashMap<>(); 23 | finalexp.put("1", new BigInteger("0")); 24 | for (String s : term) { 25 | ArrayList factor = new ArrayList<>(); 26 | Collections.addAll(factor, s.split("\\*")); 27 | HashMap map = new HashMap<>(); 28 | BigInteger sum = new BigInteger("1"); 29 | map.put("x", new BigInteger("0")); 30 | map.put("y", new BigInteger("0")); 31 | map.put("z", new BigInteger("0")); 32 | for (String value : factor) { 33 | if ("xyz".indexOf(value.charAt(0)) == -1) { 34 | sum = sum.multiply(new BigInteger(value)); 35 | } else { 36 | map.put(value, map.get(value).add(new BigInteger("1"))); 37 | } 38 | } 39 | StringBuilder sb = new StringBuilder(); 40 | int flag = 0; 41 | if (!map.get("x").equals(new BigInteger("0"))) { 42 | flag = 1; 43 | sb = join(sb, map, "x"); 44 | } 45 | if (!map.get("y").equals(new BigInteger("0"))) { 46 | if (flag == 1) { 47 | sb.append("*"); 48 | } 49 | flag = 1; 50 | sb = join(sb, map, "y"); 51 | } 52 | if (!map.get("z").equals(new BigInteger("0"))) { 53 | if (flag == 1) { 54 | sb.append("*"); 55 | } 56 | flag = 1; 57 | sb = join(sb, map, "z"); 58 | } 59 | if (flag == 0) { 60 | finalexp.put("1", finalexp.get("1").add(sum)); 61 | } else { 62 | if (finalexp.containsKey(sb.toString())) { 63 | finalexp.put(sb.toString(), finalexp.get(sb.toString()).add(sum)); 64 | } else { 65 | finalexp.put(sb.toString(), sum); 66 | } 67 | } 68 | } 69 | merge(finalexp); 70 | } 71 | 72 | public StringBuilder join(StringBuilder sb, HashMap map, String str) { 73 | sb.append(str); 74 | if (!map.get(str).equals(new BigInteger("1"))) { 75 | if (!map.get(str).equals(new BigInteger("2"))) { 76 | sb.append("**"); 77 | sb.append(map.get(str)); 78 | } else { 79 | sb.append("*"); 80 | sb.append(str); 81 | } 82 | } 83 | return sb; 84 | } 85 | 86 | public void merge(HashMap finalexp) { 87 | StringBuilder sb = new StringBuilder(); 88 | Iterator iterator = finalexp.keySet().iterator(); 89 | int flag = 0;//change 1 90 | while (iterator.hasNext()) { 91 | String next = iterator.next(); 92 | StringBuilder newsb = new StringBuilder(); 93 | if (next.equals("1")) { 94 | if (!finalexp.get(next).equals(new BigInteger("0"))) { 95 | if (finalexp.get(next).compareTo(new BigInteger("0")) > 0 && flag == 0) { 96 | newsb.append(finalexp.get(next)).append("+"); 97 | for (int m = 0; m < sb.length(); m++) { 98 | newsb.append(sb.charAt(m)); 99 | } 100 | sb = newsb; 101 | flag = 1;//change 3 102 | } else { 103 | sb.append(finalexp.get(next)).append("+"); 104 | } 105 | } 106 | } else { 107 | if (!finalexp.get(next).equals(new BigInteger("0"))) { 108 | if (finalexp.get(next).compareTo(new BigInteger("0")) > 0 && flag == 0) { 109 | if (!finalexp.get(next).equals(new BigInteger("1"))) { 110 | newsb.append(finalexp.get(next)).append("*"); 111 | } 112 | newsb.append(next).append("+"); 113 | for (int m = 0; m < sb.length(); m++) { 114 | newsb.append(sb.charAt(m)); 115 | } 116 | sb = newsb; 117 | flag = 1;//change 5 118 | } else { 119 | if (!finalexp.get(next).equals(new BigInteger("1"))) { 120 | if (!finalexp.get(next).equals(new BigInteger("-1"))) { 121 | sb.append(finalexp.get(next)).append("*"); 122 | } else { 123 | sb.append("-"); 124 | } 125 | } 126 | sb.append(next).append("+"); 127 | } 128 | } 129 | } 130 | } 131 | if (sb.toString().equals("")) { 132 | sb.append("0"); 133 | } 134 | if (sb.toString().endsWith("+")) { 135 | sb.deleteCharAt(sb.length() - 1); 136 | } 137 | String finalstr = sb.toString(); 138 | finalstr = finalstr.replaceAll("(-\\+)|(\\+-)", "-"); 139 | System.out.println(finalstr); 140 | } 141 | 142 | public String toString() { 143 | StringBuilder sb = new StringBuilder(); 144 | if (!terms.isEmpty()) { 145 | for (int i = 0; i < terms.size(); i++) { 146 | if (i > 0) { 147 | sb.append("+"); 148 | } 149 | sb.append(terms.get(i)); 150 | } 151 | } 152 | return sb.toString(); 153 | } 154 | } 155 | -------------------------------------------------------------------------------- /hw1/Factor.java: -------------------------------------------------------------------------------- 1 | public interface Factor { 2 | } 3 | -------------------------------------------------------------------------------- /hw1/Lexer.java: -------------------------------------------------------------------------------- 1 | public class Lexer { 2 | private final String input; 3 | private int pos = 0; 4 | private String curToken; 5 | 6 | public Lexer(String input) { 7 | this.input = input; 8 | this.next(); 9 | } 10 | 11 | private String getNumber() { 12 | StringBuilder sb = new StringBuilder(); 13 | while (pos < input.length() && Character.isDigit(input.charAt(pos))) { 14 | sb.append(input.charAt(pos)); 15 | ++pos; 16 | } 17 | 18 | return sb.toString(); 19 | } 20 | 21 | public void next() { 22 | if (pos == input.length()) { 23 | return; 24 | } 25 | 26 | char c = input.charAt(pos); 27 | if (Character.isDigit(c)) { 28 | curToken = getNumber(); // first 29 | } else if ("()+-*^".indexOf(c) != -1) { // second 30 | pos += 1; 31 | curToken = String.valueOf(c); 32 | } else if (Character.isLetter(c)) { 33 | pos += 1; 34 | curToken = String.valueOf(c); 35 | } 36 | } 37 | 38 | public String peek() { 39 | return this.curToken; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /hw1/MainClass.java: -------------------------------------------------------------------------------- 1 | import java.util.Scanner; 2 | 3 | public class MainClass { 4 | public static void main(String[] args) { 5 | Scanner scanner = new Scanner(System.in); 6 | String origin = scanner.nextLine(); 7 | String expression = origin.replaceAll("[ \t]", ""); 8 | StringBuilder sb = new StringBuilder(); 9 | int flag = 0; 10 | for (int i = 0; i < expression.length(); i++) { 11 | if (expression.charAt(i) == '(') { 12 | sb.append('('); 13 | if (expression.charAt(i + 1) == '+') { 14 | flag = 1; 15 | } 16 | } else if (flag == 0) { 17 | sb.append(expression.charAt(i)); 18 | } else { 19 | flag = 0; 20 | } 21 | } 22 | expression = sb.toString(); 23 | expression = expression.replaceAll("(\\+\\+)|(--)", "+"); 24 | expression = expression.replaceAll("\\*\\*", "^"); 25 | expression = expression.replaceAll("(-\\+)|(\\+-)", "-"); 26 | expression = expression.replaceAll("\\^\\+", "^"); 27 | expression = expression.replaceAll("\\*\\+", "*"); 28 | expression = expression.replaceAll("^\\+", ""); 29 | expression = expression.replaceAll("(\\+\\+)|(--)", "+"); 30 | expression = expression.replaceAll("(-\\+)|(\\+-)", "-"); 31 | expression = expression.replaceAll("^\\+", ""); 32 | Lexer lexer = new Lexer(expression); 33 | Parser parser = new Parser(lexer); 34 | 35 | Expr expr = parser.parseExpr(); 36 | expr.simplify(expr); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /hw1/Number.java: -------------------------------------------------------------------------------- 1 | import java.math.BigInteger; 2 | 3 | public class Number implements Factor { 4 | private final BigInteger num; 5 | 6 | public Number(BigInteger num) { 7 | this.num = num; 8 | } 9 | 10 | public String toString() { 11 | return this.num.toString(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /hw1/Parser.java: -------------------------------------------------------------------------------- 1 | import java.math.BigInteger; 2 | 3 | public class Parser { 4 | private final Lexer lexer; 5 | 6 | public Parser(Lexer lexer) { 7 | this.lexer = lexer; 8 | } 9 | 10 | public Expr parseExpr() { 11 | Expr expr = new Expr(); 12 | expr.addTerm(parseTerm()); 13 | 14 | while (lexer.peek().equals("+") || lexer.peek().equals("-")) { // first 15 | expr.addTerm(parseTerm()); 16 | } 17 | return expr; 18 | } 19 | 20 | public Term parseTerm() { 21 | Term term = new Term(); 22 | Factor temp; 23 | BigInteger num = new BigInteger("-1"); 24 | Factor newnum = new Number(num); 25 | BigInteger num1 = new BigInteger("1"); 26 | Factor newnum1 = new Number(num1); 27 | if (lexer.peek().equals("+")) { 28 | lexer.next(); 29 | temp = parseFactor(); 30 | } else if (lexer.peek().equals("-")) { 31 | term.addFactor(newnum); 32 | lexer.next(); 33 | temp = parseFactor(); 34 | } else { 35 | temp = parseFactor(); 36 | } 37 | if (lexer.peek().equals("^")) { 38 | lexer.next(); 39 | if (Integer.parseInt(lexer.peek()) != 0) { 40 | for (int i = 0; i < Integer.parseInt(lexer.peek()); i++) { 41 | term.addFactor(temp); 42 | } 43 | } else { 44 | term.addFactor(newnum1); 45 | } 46 | lexer.next(); 47 | } else { 48 | term.addFactor(temp); 49 | } 50 | while (lexer.peek().equals("*")) { 51 | lexer.next(); 52 | if (lexer.peek().equals("-")) { 53 | term.addFactor(newnum); 54 | lexer.next(); 55 | } 56 | temp = parseFactor(); 57 | if (lexer.peek().equals("^")) { 58 | lexer.next(); 59 | if (Integer.parseInt(lexer.peek()) != 0) { 60 | for (int i = 0; i < Integer.parseInt(lexer.peek()); i++) { 61 | term.addFactor(temp); 62 | } 63 | } else { 64 | term.addFactor(newnum1); 65 | } 66 | lexer.next(); 67 | } else { 68 | term.addFactor(temp); 69 | } 70 | } 71 | return term; 72 | } 73 | 74 | public Factor parseFactor() { 75 | if (lexer.peek().equals("(")) { 76 | lexer.next(); 77 | Factor expr = parseExpr(); 78 | lexer.next(); // third 79 | return expr; 80 | } else if (Character.isDigit(lexer.peek().charAt(0))) { 81 | BigInteger num = new BigInteger(lexer.peek()); // fourth 82 | lexer.next(); 83 | return new Number(num); 84 | } else { 85 | Factor var = new Variable(lexer.peek()); 86 | lexer.next(); 87 | return var; 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /hw1/Term.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | 3 | public class Term implements Factor { 4 | private final ArrayList factors; 5 | 6 | public Term() { 7 | this.factors = new ArrayList<>(); 8 | } 9 | 10 | public void addFactor(Factor factor) { 11 | organizeFactor(factor); 12 | } 13 | 14 | public void organizeFactor(Factor factor) { 15 | Factor add = new Variable("+"); 16 | ArrayList newfactors = new ArrayList<>(); 17 | ArrayList newterms = new ArrayList<>(); 18 | if (factor.toString().contains("+")) { 19 | String[] split = factor.toString().split("\\+"); 20 | for (String s : split) { 21 | Lexer le = new Lexer(s); 22 | Parser pa = new Parser(le); 23 | newterms.add(pa.parseTerm()); 24 | } 25 | if (!factors.isEmpty()) { 26 | for (int i = 0; i < newterms.size(); i++) { 27 | int flag = 0; 28 | for (Factor value : factors) { 29 | if (!value.toString().equals("+")) { 30 | if (flag == 0) { 31 | newfactors.add(newterms.get(i)); 32 | flag = 1; 33 | } 34 | newfactors.add(value); 35 | } else { 36 | flag = 0; 37 | newfactors.add(add); 38 | } 39 | } 40 | if (i < newterms.size() - 1) { 41 | newfactors.add(add); 42 | } 43 | } 44 | } else { 45 | for (int i = 0; i < newterms.size(); i++) { 46 | newfactors.add(newterms.get(i)); 47 | if (i < newterms.size() - 1) { 48 | newfactors.add(add); 49 | } 50 | } 51 | } 52 | } else { 53 | if (!factors.isEmpty()) { 54 | int flag = 0; 55 | for (Factor value : factors) { 56 | if (!value.toString().equals("+")) { 57 | if (flag == 0) { 58 | newfactors.add(factor); 59 | flag = 1; 60 | } 61 | newfactors.add(value); 62 | } else { 63 | flag = 0; 64 | newfactors.add(add); 65 | } 66 | } 67 | } else { 68 | newfactors.add(factor); 69 | } 70 | } 71 | factors.clear(); 72 | factors.addAll(newfactors); 73 | } 74 | 75 | public String toString() { 76 | StringBuilder sb = new StringBuilder(); 77 | int flag1 = 0; 78 | if (!factors.isEmpty()) { 79 | for (int i = 0; i < factors.size(); i++) { 80 | if (factors.get(i).toString().equals("+")) { 81 | sb.append("+"); 82 | flag1 = 1; 83 | } else { 84 | if (i > 0 && flag1 == 0) { 85 | sb.append("*"); 86 | } 87 | sb.append(factors.get(i).toString()); 88 | flag1 = 0; 89 | } 90 | } 91 | } 92 | return sb.toString(); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /hw1/Variable.java: -------------------------------------------------------------------------------- 1 | public class Variable implements Factor { 2 | private final String var; 3 | 4 | public Variable(String var) { 5 | this.var = var; 6 | } 7 | 8 | public String toString() { 9 | return var; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /hw2/Cos.java: -------------------------------------------------------------------------------- 1 | public class Cos implements Factor { 2 | private final Expr expression; 3 | 4 | public Cos(Expr expression) { 5 | this.expression = expression; 6 | } 7 | 8 | public String toString() { 9 | String temp = expression.simplify(expression); 10 | if (temp.equals("0")) { 11 | return "1"; 12 | } else { 13 | String str; 14 | String temp1 = temp.replaceAll("\\*\\*", "^"); 15 | if (expression.isExprFactor(temp1)) { 16 | if (temp1.startsWith("-")) { 17 | str = "cos((" + expression.reverse(temp) + "))"; 18 | } else { 19 | str = "cos((" + temp + "))"; 20 | } 21 | } else { 22 | if (temp1.startsWith("-")) { 23 | str = "cos(" + expression.reverse(temp) + ")"; 24 | } else { 25 | str = "cos(" + temp + ")"; 26 | } 27 | } 28 | return str; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /hw2/Expr.java: -------------------------------------------------------------------------------- 1 | import java.math.BigInteger; 2 | import java.util.ArrayList; 3 | import java.util.HashMap; 4 | import java.util.Iterator; 5 | import java.util.TreeMap; 6 | 7 | public class Expr implements Factor { 8 | private final ArrayList terms; 9 | 10 | public Expr() { 11 | this.terms = new ArrayList<>(); 12 | } 13 | 14 | public void addTerm(Term term) { 15 | this.terms.add(term); 16 | } 17 | 18 | public String simplify(Expr expr) { 19 | HashMap finalexp = new HashMap<>(); 20 | finalexp.put("1", new BigInteger("0")); 21 | ArrayList doublesin = new ArrayList<>(); 22 | ArrayList> indexsin = new ArrayList<>(); 23 | ArrayList doublecos = new ArrayList<>(); 24 | ArrayList> indexcos = new ArrayList<>(); 25 | for (String s : getTerm(expr.toString())) { 26 | HashMap map = new HashMap<>(); 27 | getFactor(s, map); 28 | triMatchPro(doublesin, indexsin, doublecos, indexcos, map, finalexp); 29 | String term = joinMap(map); 30 | addFinal(term, map, finalexp); 31 | } 32 | return merge(finalexp); 33 | } 34 | 35 | public void triMatchPro(ArrayList doublesin, 36 | ArrayList> indexsin, 37 | ArrayList doublecos, 38 | ArrayList> indexcos, 39 | HashMap map, HashMap finalexp) { 40 | Iterator iterator = map.keySet().iterator(); 41 | while (iterator.hasNext()) { 42 | String next = iterator.next(); 43 | BigInteger index = map.get(next); 44 | if (next.startsWith("s") && index.compareTo(new BigInteger("2")) >= 0) { 45 | int temp = triMatch(doublecos, indexcos, map, next, finalexp); 46 | if (temp != 1) { 47 | if (!match(doublesin, indexsin, map, next)) { 48 | doublesin.add(next); 49 | indexsin.add(map); 50 | } 51 | } 52 | if (temp != 0) { 53 | triMatchPro(doublesin, indexsin, doublecos, indexcos, map, finalexp); 54 | } 55 | } else if (next.startsWith("c") && index.compareTo(new BigInteger("2")) >= 0) { 56 | int temp = triMatch(doublesin, indexsin, map, next, finalexp); 57 | if (temp != 1) { 58 | if (!match(doublecos, indexcos, map, next)) { 59 | doublecos.add(next); 60 | indexcos.add(map); 61 | } 62 | } 63 | if (temp != 0) { 64 | triMatchPro(doublesin, indexsin, doublecos, indexcos, map, finalexp); 65 | } 66 | } 67 | } 68 | } 69 | 70 | public void deepCopy(HashMap des, 71 | HashMap src) { 72 | for (String next : src.keySet()) { 73 | des.put(next, src.get(next)); 74 | } 75 | } 76 | 77 | public int triMatch(ArrayList name, ArrayList> index, 78 | HashMap maindex, String match, 79 | HashMap finalexp) { 80 | int flag = 0; 81 | for (int i = 0; i < name.size(); i++) { 82 | if (name.get(i).substring(3).equals(match.substring(3))) { 83 | if (triMapEqual(index.get(i), name.get(i), maindex, match)) { 84 | flag = 1; 85 | String change = joinMap(index.get(i)); 86 | if (finalexp.get(change).compareTo(maindex.get("1")) > 0) { 87 | finalexp.put(change, finalexp.get(change).subtract(maindex.get("1"))); 88 | maindex.put(match, maindex.get(match).subtract(new BigInteger("2"))); 89 | } else if (finalexp.get(change).compareTo(maindex.get("1")) < 0) { 90 | flag = 2; 91 | index.get(i).put(name.get(i), 92 | index.get(i).get(name.get(i)).subtract(new BigInteger("2"))); 93 | maindex.put("1", maindex.get("1").subtract(finalexp.get(change))); 94 | index.get(i).put("1", finalexp.get(change)); 95 | finalexp.remove(change); 96 | String newterm = joinMap(index.get(i)); 97 | addFinal(newterm, index.get(i), finalexp); 98 | name.remove(i); 99 | index.remove(i); 100 | break; 101 | } else { 102 | maindex.put(match, maindex.get(match).subtract(new BigInteger("2"))); 103 | index.get(i).put(name.get(i), 104 | index.get(i).get(name.get(i)).subtract(new BigInteger("2"))); 105 | finalexp.remove(change); 106 | name.remove(i); 107 | index.remove(i); 108 | break; 109 | } 110 | } 111 | } 112 | } 113 | return flag; 114 | } 115 | 116 | public boolean match(ArrayList name, ArrayList> index, 117 | HashMap maindex, String match) { 118 | boolean flag = false; 119 | for (int i = 0; i < name.size(); i++) { 120 | if (name.get(i).equals(match)) { 121 | if (triMapEqual(index.get(i), name.get(i), maindex, match)) { 122 | flag = true; 123 | } 124 | } 125 | } 126 | return flag; 127 | } 128 | 129 | public boolean triMapEqual(HashMap map1, String remove1, 130 | HashMap map2, String remove2) { 131 | HashMap cmap1 = new HashMap<>(); 132 | HashMap cmap2 = new HashMap<>(); 133 | for (String next : map1.keySet()) { 134 | cmap1.put(next, map1.get(next)); 135 | } 136 | for (String next : map2.keySet()) { 137 | cmap2.put(next, map2.get(next)); 138 | } 139 | cmap1.put(remove1, cmap1.get(remove1).subtract(new BigInteger("2"))); 140 | cmap2.put(remove2, cmap2.get(remove2).subtract(new BigInteger("2"))); 141 | return joinMap(cmap1).equals(joinMap(cmap2)); 142 | } 143 | 144 | public void addFinal(String term, HashMap map, 145 | HashMap finalexp) { 146 | if (map.size() > 1) { 147 | if (finalexp.containsKey(term)) { 148 | finalexp.put(term, finalexp.get(term).add(map.get("1"))); 149 | } else { 150 | finalexp.put(term, map.get("1")); 151 | } 152 | } else { 153 | finalexp.put("1", finalexp.get("1").add(map.get("1"))); 154 | } 155 | } 156 | 157 | public String joinMap(HashMap map) { 158 | StringBuilder sb = new StringBuilder(); 159 | int flag = 0; 160 | TreeMap sort = new TreeMap<>(map); 161 | for (String next : sort.keySet()) { 162 | if (map.get(next).equals(new BigInteger("0"))) { 163 | sb.append(""); 164 | } else if (!next.equals("1")) { 165 | if (flag == 1) { 166 | sb.append("*"); 167 | } 168 | flag = 1; 169 | sb = join(sb, map, next); 170 | } 171 | } 172 | if (sb.length() == 0) { 173 | sb.append("1"); 174 | } 175 | return sb.toString(); 176 | } 177 | 178 | public ArrayList getTerm(String exp) { 179 | ArrayList term = new ArrayList<>(); 180 | int last = 0; 181 | int count = 0; 182 | for (int i = 0; i < exp.length(); i++) { 183 | if (count == 0 && exp.charAt(i) == '+' && i > 0) { 184 | term.add(exp.substring(last, i)); 185 | last = i + 1; 186 | } else if (exp.charAt(i) == '(') { 187 | count--; 188 | } else if (exp.charAt(i) == ')') { 189 | count++; 190 | } 191 | } 192 | term.add(exp.substring(last)); 193 | return term; 194 | } 195 | 196 | public void getFactor(String s, HashMap map) { 197 | ArrayList factor = new ArrayList<>(); 198 | int last = 0; 199 | int count = 0; 200 | for (int i = 0; i < s.length(); i++) { 201 | if (count == 0 && s.charAt(i) == '*' && i > 0) { 202 | factor.add(s.substring(last, i)); 203 | last = i + 1; 204 | } else if (s.charAt(i) == '(') { 205 | count--; 206 | } else if (s.charAt(i) == ')') { 207 | count++; 208 | } 209 | } 210 | factor.add(s.substring(last)); 211 | map.put("1", new BigInteger("1")); 212 | for (String value : factor) { 213 | if ("xyzsc".indexOf(value.charAt(0)) != -1) { 214 | if (map.containsKey(value)) { 215 | map.put(value, map.get(value).add(new BigInteger("1"))); 216 | } else { 217 | map.put(value, new BigInteger("1")); 218 | } 219 | } else { 220 | map.put("1", map.get("1").multiply(new BigInteger(value))); 221 | } 222 | } 223 | } 224 | 225 | public StringBuilder join(StringBuilder sb, HashMap map, String str) { 226 | sb.append(str); 227 | if (!map.get(str).equals(new BigInteger("1"))) { 228 | if (map.get(str).equals(new BigInteger("2")) && "sc".indexOf(str.charAt(0)) == -1) { 229 | sb.append("*"); 230 | sb.append(str); 231 | } else { 232 | sb.append("**"); 233 | sb.append(map.get(str)); 234 | } 235 | } 236 | return sb; 237 | } 238 | 239 | public String merge(HashMap finalexp) { 240 | StringBuilder sb = new StringBuilder(); 241 | TreeMap sort = new TreeMap<>(finalexp); 242 | Iterator iterator = sort.keySet().iterator(); 243 | int flag = 0; 244 | while (iterator.hasNext()) { 245 | String next = iterator.next(); 246 | StringBuilder newsb = new StringBuilder(); 247 | if (next.equals("1")) { 248 | if (!finalexp.get(next).equals(new BigInteger("0"))) { 249 | if (finalexp.get(next).compareTo(new BigInteger("0")) > 0 && flag == 0) { 250 | newsb.append(finalexp.get(next)).append("+"); 251 | for (int m = 0; m < sb.length(); m++) { 252 | newsb.append(sb.charAt(m)); 253 | } 254 | sb = newsb; 255 | flag = 1; 256 | } else { 257 | sb.append(finalexp.get(next)).append("+"); 258 | } 259 | } 260 | } else { 261 | if (!finalexp.get(next).equals(new BigInteger("0"))) { 262 | if (finalexp.get(next).compareTo(new BigInteger("0")) > 0 && flag == 0) { 263 | if (!finalexp.get(next).equals(new BigInteger("1"))) { 264 | newsb.append(finalexp.get(next)).append("*"); 265 | } 266 | newsb.append(next).append("+"); 267 | for (int m = 0; m < sb.length(); m++) { 268 | newsb.append(sb.charAt(m)); 269 | } 270 | sb = newsb; 271 | flag = 1; 272 | } else { 273 | if (!finalexp.get(next).equals(new BigInteger("1"))) { 274 | if (!finalexp.get(next).equals(new BigInteger("-1"))) { 275 | sb.append(finalexp.get(next)).append("*"); 276 | } else { 277 | sb.append("-"); 278 | } 279 | } 280 | sb.append(next).append("+"); 281 | } 282 | } 283 | } 284 | } 285 | if (sb.toString().equals("")) { 286 | sb.append("0"); 287 | } 288 | if (sb.toString().endsWith("+")) { 289 | sb.deleteCharAt(sb.length() - 1); 290 | } 291 | String finalstr = sb.toString(); 292 | finalstr = finalstr.replaceAll("(-\\+)|(\\+-)", "-"); 293 | return finalstr; 294 | } 295 | 296 | public String reverse(String src) { 297 | int flag = 0; 298 | StringBuilder sb = new StringBuilder(); 299 | for (int i = 0; i < src.length(); i++) { 300 | if (flag == 0 && src.charAt(i) == '-') { 301 | if (i > 0) { 302 | sb.append("+"); 303 | } 304 | } else if (src.charAt(i) == '(') { 305 | sb.append("("); 306 | flag--; 307 | } else if (src.charAt(i) == ')') { 308 | sb.append(")"); 309 | flag++; 310 | } else { 311 | sb.append(src.charAt(i)); 312 | } 313 | } 314 | return sb.toString(); 315 | } 316 | 317 | public boolean isExprFactor(String str) { 318 | boolean flag = false; 319 | int count = 0; 320 | for (int i = 0; i < str.length(); i++) { 321 | if (count == 0 && ("+-*".indexOf(str.charAt(i)) != -1) && i > 0) { 322 | flag = true; 323 | return flag; 324 | } else if (str.charAt(i) == '(') { 325 | count--; 326 | } else if (str.charAt(i) == ')') { 327 | count++; 328 | } 329 | } 330 | return flag; 331 | } 332 | 333 | public String toString() { 334 | StringBuilder sb = new StringBuilder(); 335 | if (!terms.isEmpty()) { 336 | for (int i = 0; i < terms.size(); i++) { 337 | if (i > 0) { 338 | sb.append("+"); 339 | } 340 | sb.append(terms.get(i)); 341 | } 342 | } 343 | return sb.toString(); 344 | } 345 | } 346 | -------------------------------------------------------------------------------- /hw2/Factor.java: -------------------------------------------------------------------------------- 1 | public interface Factor { 2 | } 3 | -------------------------------------------------------------------------------- /hw2/Lexer.java: -------------------------------------------------------------------------------- 1 | public class Lexer { 2 | private final String input; 3 | private int pos = 0; 4 | private String curToken; 5 | 6 | public Lexer(String input) { 7 | this.input = input; 8 | this.next(); 9 | } 10 | 11 | private String getNumber() { 12 | StringBuilder sb = new StringBuilder(); 13 | while (pos < input.length() && Character.isDigit(input.charAt(pos))) { 14 | sb.append(input.charAt(pos)); 15 | ++pos; 16 | } 17 | 18 | return sb.toString(); 19 | } 20 | 21 | public void next() { 22 | if (pos == input.length()) { 23 | return; 24 | } 25 | char c = input.charAt(pos); 26 | if (Character.isDigit(c)) { 27 | curToken = getNumber(); // first 28 | } else if ("()+-*^,!@#".indexOf(c) != -1) { // second 29 | pos += 1; 30 | curToken = String.valueOf(c); 31 | } else if (c == 's' || c == 'c') { 32 | pos += 4; 33 | if (c == 's') { 34 | curToken = "sin"; 35 | } else { 36 | curToken = "cos"; 37 | } 38 | } else if (Character.isLetter(c)) { 39 | pos += 1; 40 | curToken = String.valueOf(c); 41 | } 42 | } 43 | 44 | public String peek() { 45 | return this.curToken; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /hw2/MainClass.java: -------------------------------------------------------------------------------- 1 | import java.util.Scanner; 2 | 3 | public class MainClass { 4 | private static SelfDefine functionF; 5 | private static SelfDefine functionG; 6 | private static SelfDefine functionH; 7 | 8 | public static SelfDefine getFunction(String name) { 9 | if (name.equals("f")) { 10 | return functionF; 11 | } else if (name.equals("g")) { 12 | return functionG; 13 | } else { 14 | return functionH; 15 | } 16 | } 17 | 18 | public static void iniFunction(String function) { 19 | if (function.indexOf('f') != -1) { 20 | functionF = new SelfDefine(function); 21 | } else if (function.indexOf('g') != -1) { 22 | functionG = new SelfDefine(function); 23 | } else if (function.indexOf('h') != -1) { 24 | functionH = new SelfDefine(function); 25 | } 26 | } 27 | 28 | public static void main(String[] args) { 29 | Scanner scanner = new Scanner(System.in); 30 | String count = scanner.nextLine(); 31 | for (int i = 0; i < Integer.parseInt(count); i++) { 32 | String function = scanner.nextLine(); 33 | iniFunction(function); 34 | } 35 | String origin = scanner.nextLine(); 36 | StringSimplify st = new StringSimplify(origin); 37 | String expression = st.simplify(); 38 | Lexer lexer = new Lexer(expression); 39 | Parser parser = new Parser(lexer); 40 | 41 | Expr expr = parser.parseExpr(); 42 | System.out.println(expr.simplify(expr)); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /hw2/Number.java: -------------------------------------------------------------------------------- 1 | import java.math.BigInteger; 2 | 3 | public class Number implements Factor { 4 | private final BigInteger num; 5 | 6 | public Number(BigInteger num) { 7 | this.num = num; 8 | } 9 | 10 | public String toString() { 11 | return this.num.toString(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /hw2/Parser.java: -------------------------------------------------------------------------------- 1 | import java.math.BigInteger; 2 | 3 | public class Parser { 4 | private final Lexer lexer; 5 | private Factor x1; 6 | private Factor y1; 7 | private Factor z1; 8 | 9 | public Parser(Lexer lexer) { 10 | this.lexer = lexer; 11 | } 12 | 13 | public Parser(Lexer lexer, Factor x, Factor y, Factor z) { 14 | this.lexer = lexer; 15 | this.x1 = x; 16 | this.y1 = y; 17 | this.z1 = z; 18 | } 19 | 20 | public Expr parseExpr() { 21 | Expr expr = new Expr(); 22 | expr.addTerm(parseTerm()); 23 | 24 | while (lexer.peek().equals("+") || lexer.peek().equals("-")) { // first 25 | expr.addTerm(parseTerm()); 26 | } 27 | return expr; 28 | } 29 | 30 | public Term parseTerm() { 31 | Term term = new Term(); 32 | Factor temp; 33 | BigInteger num = new BigInteger("-1"); 34 | Factor newnum = new Number(num); 35 | BigInteger num1 = new BigInteger("1"); 36 | Factor newnum1 = new Number(num1); 37 | if (lexer.peek().equals("+")) { 38 | lexer.next(); 39 | temp = parseFactor(); 40 | } else if (lexer.peek().equals("-")) { 41 | term.addFactor(newnum); 42 | lexer.next(); 43 | temp = parseFactor(); 44 | } else { 45 | temp = parseFactor(); 46 | } 47 | if (lexer.peek().equals("^")) { 48 | lexer.next(); 49 | if (Integer.parseInt(lexer.peek()) != 0) { 50 | for (int i = 0; i < Integer.parseInt(lexer.peek()); i++) { 51 | term.addFactor(temp); 52 | } 53 | } else { 54 | term.addFactor(newnum1); 55 | } 56 | lexer.next(); 57 | } else { 58 | term.addFactor(temp); 59 | } 60 | while (lexer.peek().equals("*")) { 61 | lexer.next(); 62 | if (lexer.peek().equals("-")) { 63 | term.addFactor(newnum); 64 | lexer.next(); 65 | } 66 | temp = parseFactor(); 67 | if (lexer.peek().equals("^")) { 68 | lexer.next(); 69 | if (Integer.parseInt(lexer.peek()) != 0) { 70 | for (int i = 0; i < Integer.parseInt(lexer.peek()); i++) { 71 | term.addFactor(temp); 72 | } 73 | } else { 74 | term.addFactor(newnum1); 75 | } 76 | lexer.next(); 77 | } else { 78 | term.addFactor(temp); 79 | } 80 | } 81 | return term; 82 | } 83 | 84 | public Factor parseFactor() { 85 | if (lexer.peek().equals("(")) { 86 | lexer.next(); 87 | Factor expr = parseExpr(); 88 | lexer.next(); // third 89 | return expr; 90 | } else if (lexer.peek().equals("-")) { 91 | doubleNext(); 92 | return new Number(new BigInteger("-1")); 93 | } else if (Character.isDigit(lexer.peek().charAt(0))) { 94 | BigInteger num = new BigInteger(lexer.peek()); // fourth 95 | lexer.next(); 96 | return new Number(num); 97 | } else if ("fgh".indexOf(lexer.peek().charAt(0)) != -1) { 98 | Factor x; 99 | Factor y = null; 100 | Factor z = null; 101 | int count = 1; 102 | final String name = lexer.peek(); 103 | doubleNext(); 104 | x = parseExpr(); 105 | while (lexer.peek().equals(",")) { 106 | lexer.next(); 107 | count++; 108 | if (count == 2) { 109 | y = parseExpr(); 110 | } else { 111 | z = parseExpr(); 112 | } 113 | } 114 | lexer.next(); 115 | return MainClass.getFunction(name).calDefine(x, y, z); 116 | } else if ("!@#".indexOf(lexer.peek().charAt(0)) != -1) { 117 | if (lexer.peek().equals("!")) { 118 | lexer.next(); 119 | return x1; 120 | } else if (lexer.peek().equals("@")) { 121 | lexer.next(); 122 | return y1; 123 | } else { 124 | lexer.next(); 125 | return z1; 126 | } 127 | } else if (lexer.peek().equals("sin") || lexer.peek().equals("cos")) { 128 | Factor circular; 129 | String tri = lexer.peek(); 130 | lexer.next(); 131 | if (tri.equals("sin")) { 132 | circular = new Sin(parseExpr()); 133 | } else { 134 | circular = new Cos(parseExpr()); 135 | } 136 | lexer.next(); 137 | return circular; 138 | } else { 139 | Factor var = new Variable(lexer.peek()); 140 | lexer.next(); 141 | return var; 142 | } 143 | } 144 | 145 | public void doubleNext() { 146 | lexer.next(); 147 | lexer.next(); 148 | } 149 | } 150 | -------------------------------------------------------------------------------- /hw2/SelfDefine.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | 3 | public class SelfDefine implements Factor { 4 | private final String define; 5 | private final ArrayList para = new ArrayList<>(); 6 | 7 | public SelfDefine(String define) { 8 | StringSimplify st = new StringSimplify(define); 9 | String dispose = st.simplify(); 10 | String parameter = dispose.substring(0, dispose.indexOf('=')); 11 | for (int i = 0; i < parameter.length(); i++) { 12 | if ("xyz".indexOf(parameter.charAt(i)) != -1) { 13 | para.add(String.valueOf(parameter.charAt(i))); 14 | } 15 | } 16 | dispose = dispose.substring(dispose.indexOf('=') + 1); 17 | dispose = dispose.replaceAll("x", "!"); 18 | dispose = dispose.replaceAll("y", "@"); 19 | dispose = dispose.replaceAll("z", "#"); 20 | this.define = dispose; 21 | } 22 | 23 | public Expr calDefine(Factor x, Factor y, Factor z) { 24 | Lexer lexer; 25 | Factor a = null; 26 | Factor b = null; 27 | Factor c = null; 28 | lexer = new Lexer(define); 29 | for (int i = 0; i < para.size(); i++) { 30 | Factor temp; 31 | temp = temp(i, x, y, z); 32 | if (para.get(i).equals("x")) { 33 | a = temp; 34 | } else if (para.get(i).equals("y")) { 35 | b = temp; 36 | } else if (para.get(i).equals("z")) { 37 | c = temp; 38 | } 39 | } 40 | Parser parser = new Parser(lexer, a, b, c); 41 | return parser.parseExpr(); 42 | } 43 | 44 | public Factor temp(int i, Factor x, Factor y, Factor z) { 45 | if (i == 0) { 46 | return x; 47 | } else if (i == 1) { 48 | return y; 49 | } else { 50 | return z; 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /hw2/Sin.java: -------------------------------------------------------------------------------- 1 | public class Sin implements Factor { 2 | private final Expr expression; 3 | 4 | public Sin(Expr expression) { 5 | this.expression = expression; 6 | } 7 | 8 | public String toString() { 9 | String temp = expression.simplify(expression); 10 | if (temp.equals("0")) { 11 | return "0"; 12 | } else { 13 | String str; 14 | String temp1 = temp.replaceAll("\\*\\*", "^"); 15 | if (expression.isExprFactor(temp1)) { 16 | if (temp1.startsWith("-")) { 17 | str = "-1*sin((" + expression.reverse(temp) + "))"; 18 | } else { 19 | str = "sin((" + temp + "))"; 20 | } 21 | } else { 22 | if (temp1.startsWith("-")) { 23 | str = "-1*sin(" + expression.reverse(temp) + ")"; 24 | } else { 25 | str = "sin(" + temp + ")"; 26 | } 27 | } 28 | return str; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /hw2/StringSimplify.java: -------------------------------------------------------------------------------- 1 | public class StringSimplify { 2 | private final String origin; 3 | 4 | public StringSimplify(String origin) { 5 | this.origin = origin; 6 | } 7 | 8 | public String simplify() { 9 | String expression = origin.replaceAll("[ \t]", ""); 10 | expression = expression.replaceAll("\\(\\+", "("); 11 | expression = expression.replaceAll("(\\+\\+)|(--)", "+"); 12 | expression = expression.replaceAll("\\*\\*", "^"); 13 | expression = expression.replaceAll("(-\\+)|(\\+-)", "-"); 14 | expression = expression.replaceAll("\\^\\+", "^"); 15 | expression = expression.replaceAll("\\*\\+", "*"); 16 | expression = expression.replaceAll("^\\+", ""); 17 | expression = expression.replaceAll("(\\+\\+)|(--)", "+"); 18 | expression = expression.replaceAll("(-\\+)|(\\+-)", "-"); 19 | expression = expression.replaceAll("^\\+", ""); 20 | return expression; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /hw2/Term.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | 3 | public class Term implements Factor { 4 | private final ArrayList factors; 5 | 6 | public Term() { 7 | this.factors = new ArrayList<>(); 8 | } 9 | 10 | public void addFactor(Factor factor) { 11 | organizeFactor(factor); 12 | } 13 | 14 | public void organizeFactor(Factor factor) { 15 | Factor add = new Variable("+"); 16 | ArrayList newfactors = new ArrayList<>(); 17 | ArrayList newterms = new ArrayList<>(); 18 | if (isExpr(factor)) { 19 | newterms = getNewTerms(factor); 20 | if (!factors.isEmpty()) { 21 | for (int i = 0; i < newterms.size(); i++) { 22 | int flag = 0; 23 | for (Factor value : factors) { 24 | if (!value.toString().equals("+")) { 25 | if (flag == 0) { 26 | newfactors.add(newterms.get(i)); 27 | flag = 1; 28 | } 29 | newfactors.add(value); 30 | } else { 31 | flag = 0; 32 | newfactors.add(add); 33 | } 34 | } 35 | if (i < newterms.size() - 1) { 36 | newfactors.add(add); 37 | } 38 | } 39 | } else { 40 | for (int i = 0; i < newterms.size(); i++) { 41 | newfactors.add(newterms.get(i)); 42 | if (i < newterms.size() - 1) { 43 | newfactors.add(add); 44 | } 45 | } 46 | } 47 | } else { 48 | if (!factors.isEmpty()) { 49 | int flag = 0; 50 | for (Factor value : factors) { 51 | if (!value.toString().equals("+")) { 52 | if (flag == 0) { 53 | newfactors.add(factor); 54 | flag = 1; 55 | } 56 | newfactors.add(value); 57 | } else { 58 | flag = 0; 59 | newfactors.add(add); 60 | } 61 | } 62 | } else { 63 | newfactors.add(factor); 64 | } 65 | } 66 | factors.clear(); 67 | factors.addAll(newfactors); 68 | } 69 | 70 | public ArrayList getNewTerms(Factor factor) { 71 | ArrayList term = new ArrayList<>(); 72 | String temp = factor.toString().replaceAll("\\*\\*","^"); 73 | Lexer le = new Lexer(temp); 74 | Parser pa = new Parser(le); 75 | term.add(pa.parseTerm()); 76 | while (le.peek().equals("+")) { 77 | le.next(); 78 | term.add(pa.parseTerm()); 79 | } 80 | return term; 81 | } 82 | 83 | public boolean isExpr(Factor factor) { 84 | String str = factor.toString(); 85 | boolean flag = false; 86 | int count = 0; 87 | for (int i = 0; i < str.length(); i++) { 88 | if (count == 0 && str.charAt(i) == '+' && i > 0) { 89 | flag = true; 90 | return flag; 91 | } else if (str.charAt(i) == '(') { 92 | count--; 93 | } else if (str.charAt(i) == ')') { 94 | count++; 95 | } 96 | } 97 | return flag; 98 | } 99 | 100 | public String toString() { 101 | StringBuilder sb = new StringBuilder(); 102 | int flag1 = 0; 103 | if (!factors.isEmpty()) { 104 | for (int i = 0; i < factors.size(); i++) { 105 | if (factors.get(i).toString().equals("+")) { 106 | sb.append("+"); 107 | flag1 = 1; 108 | } else { 109 | if (i > 0 && flag1 == 0) { 110 | sb.append("*"); 111 | } 112 | sb.append(factors.get(i).toString()); 113 | flag1 = 0; 114 | } 115 | } 116 | } 117 | return sb.toString(); 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /hw2/Variable.java: -------------------------------------------------------------------------------- 1 | public class Variable implements Factor { 2 | private final String var; 3 | 4 | public Variable(String var) { 5 | this.var = var; 6 | } 7 | 8 | public String toString() { 9 | return var; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /hw3/Cos.java: -------------------------------------------------------------------------------- 1 | public class Cos implements Factor { 2 | private final Expr expression; 3 | 4 | public Cos(Expr expression) { 5 | this.expression = expression; 6 | } 7 | 8 | public String toString() { 9 | String temp = expression.simplify(expression); 10 | if (temp.equals("0")) { 11 | return "1"; 12 | } else { 13 | String str; 14 | String temp1 = temp.replaceAll("\\*\\*", "^"); 15 | if (expression.isExprFactor(temp1)) { 16 | if (temp1.startsWith("-")) { 17 | str = "cos((" + expression.reverse(temp) + "))"; 18 | } else { 19 | str = "cos((" + temp + "))"; 20 | } 21 | } else { 22 | if (temp1.startsWith("-")) { 23 | str = "cos(" + expression.reverse(temp) + ")"; 24 | } else { 25 | str = "cos(" + temp + ")"; 26 | } 27 | } 28 | return str; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /hw3/DeCos.java: -------------------------------------------------------------------------------- 1 | public class DeCos implements Factor { 2 | private final Expr expression; 3 | 4 | private final String para; 5 | 6 | public DeCos(Expr expression, String para) { 7 | this.expression = expression; 8 | this.para = para; 9 | } 10 | 11 | public String toString() { 12 | String temp = expression.simplify(expression); 13 | String temp1 = temp.replaceAll("\\*\\*", "^"); 14 | if (temp.equals("0")) { 15 | return "0"; 16 | } else if (temp.indexOf(para.charAt(0)) == -1) { 17 | return "0"; 18 | } else { 19 | Lexer lexer = new Lexer(temp1); 20 | Derivative derivative = new Derivative("d" + para, lexer); 21 | String temp2 = derivative.deExpr().toString(); 22 | temp2 = temp2.replaceAll("\\*\\*", "^"); 23 | String str = "(" + reverseString(temp1) + ")" + "*(" + temp2 + ")"; 24 | Lexer lexer1 = new Lexer(str); 25 | Parser parser = new Parser(lexer1); 26 | return parser.parseExpr().toString(); 27 | } 28 | } 29 | 30 | public String oriString(String temp) { 31 | String str; 32 | String temp1 = temp.replaceAll("\\*\\*", "^"); 33 | if (expression.isExprFactor(temp1)) { 34 | if (temp1.startsWith("-")) { 35 | str = "cos((" + expression.reverse(temp) + "))"; 36 | } else { 37 | str = "cos((" + temp + "))"; 38 | } 39 | } else { 40 | if (temp1.startsWith("-")) { 41 | str = "cos(" + expression.reverse(temp) + ")"; 42 | } else { 43 | str = "cos(" + temp + ")"; 44 | } 45 | } 46 | return str; 47 | } 48 | 49 | public String reverseString(String temp) { 50 | String str; 51 | String temp1 = temp.replaceAll("\\*\\*", "^"); 52 | if (expression.isExprFactor(temp1)) { 53 | if (temp1.startsWith("-")) { 54 | str = "sin((" + expression.reverse(temp) + "))"; 55 | } else { 56 | str = "-1*sin((" + temp + "))"; 57 | } 58 | } else { 59 | if (temp1.startsWith("-")) { 60 | str = "sin(" + expression.reverse(temp) + ")"; 61 | } else { 62 | str = "-1*sin(" + temp + ")"; 63 | } 64 | } 65 | return str; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /hw3/DeSin.java: -------------------------------------------------------------------------------- 1 | public class DeSin implements Factor { 2 | private final Expr expression; 3 | 4 | private final String para; 5 | 6 | public DeSin(Expr expression, String para) { 7 | this.expression = expression; 8 | this.para = para; 9 | } 10 | 11 | public String toString() { 12 | String temp = expression.simplify(expression); 13 | String temp1 = temp.replaceAll("\\*\\*", "^"); 14 | if (temp.equals("0")) { 15 | return "0"; 16 | } else if (temp.indexOf(para.charAt(0)) == -1) { 17 | return "0"; 18 | } else { 19 | Lexer lexer = new Lexer(temp1); 20 | Derivative derivative = new Derivative("d" + para, lexer); 21 | String temp2 = derivative.deExpr().toString(); 22 | temp2 = temp2.replaceAll("\\*\\*", "^"); 23 | String str = "(" + reverseString(temp1) + ")" + "*(" + temp2 + ")"; 24 | Lexer lexer1 = new Lexer(str); 25 | Parser parser = new Parser(lexer1); 26 | return parser.parseExpr().toString(); 27 | } 28 | } 29 | 30 | public String oriString(String temp) { 31 | String str; 32 | String temp1 = temp.replaceAll("\\*\\*", "^"); 33 | if (expression.isExprFactor(temp1)) { 34 | if (temp1.startsWith("-")) { 35 | str = "-1*sin((" + expression.reverse(temp) + "))"; 36 | } else { 37 | str = "sin((" + temp + "))"; 38 | } 39 | } else { 40 | if (temp1.startsWith("-")) { 41 | str = "-1*sin(" + expression.reverse(temp) + ")"; 42 | } else { 43 | str = "sin(" + temp + ")"; 44 | } 45 | } 46 | return str; 47 | } 48 | 49 | public String reverseString(String temp) { 50 | String str; 51 | String temp1 = temp.replaceAll("\\*\\*", "^"); 52 | if (expression.isExprFactor(temp1)) { 53 | if (temp1.startsWith("-")) { 54 | str = "cos((" + expression.reverse(temp) + "))"; 55 | } else { 56 | str = "cos((" + temp + "))"; 57 | } 58 | } else { 59 | if (temp1.startsWith("-")) { 60 | str = "cos(" + expression.reverse(temp) + ")"; 61 | } else { 62 | str = "cos(" + temp + ")"; 63 | } 64 | } 65 | return str; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /hw3/DeVariable.java: -------------------------------------------------------------------------------- 1 | public class DeVariable implements Factor { 2 | private final String var; 3 | 4 | public DeVariable(String var) { 5 | this.var = var; 6 | } 7 | 8 | public String toString() { 9 | return "1"; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /hw3/Derivative.java: -------------------------------------------------------------------------------- 1 | import java.math.BigInteger; 2 | import java.util.ArrayList; 3 | 4 | public class Derivative implements Factor { 5 | private final String para; 6 | private final Lexer lexer; 7 | 8 | public Derivative(String name, Lexer lexer) { 9 | this.para = name.substring(1); 10 | this.lexer = lexer; 11 | } 12 | 13 | public Expr deExpr() { 14 | Expr expr = new Expr(); 15 | expr.addTerm(deTerm()); 16 | while (lexer.peek().equals("+") || lexer.peek().equals("-")) { 17 | expr.addTerm(deTerm()); 18 | } 19 | return expr; 20 | } 21 | 22 | public Term deTerm() { 23 | Term term = new Term(); 24 | ArrayList orlist = new ArrayList<>(); 25 | ArrayList delist = new ArrayList<>(); 26 | getFirstFactor(orlist, delist); 27 | getOtherFactor(orlist, delist); 28 | term.multiTerm(orlist, delist); 29 | return term; 30 | } 31 | 32 | public void getFirstFactor(ArrayList orlist, ArrayList delist) { 33 | Factor tempor; 34 | Factor tempde; 35 | Factor newnum = new Number(new BigInteger("-1")); 36 | Factor newnum1 = new Number(new BigInteger("1")); 37 | Factor newnum0 = new Number(new BigInteger("0")); 38 | if (lexer.peek().equals("+")) { 39 | Lexer lexer1 = new Lexer(lexer); 40 | lexer1.next(); 41 | Parser parser = new Parser(lexer1); 42 | tempor = parser.parseFactor(); 43 | lexer.next(); 44 | tempde = deFactor(); 45 | } else if (lexer.peek().equals("-")) { 46 | orlist.add(newnum); 47 | delist.add(newnum0); 48 | Lexer lexer1 = new Lexer(lexer); 49 | lexer1.next(); 50 | Parser parser = new Parser(lexer1); 51 | tempor = parser.parseFactor(); 52 | lexer.next(); 53 | tempde = deFactor(); 54 | } else { 55 | Lexer lexer1 = new Lexer(lexer); 56 | Parser parser = new Parser(lexer1); 57 | tempor = parser.parseFactor(); 58 | tempde = deFactor(); 59 | } 60 | if (lexer.peek().equals("^")) { 61 | lexer.next(); 62 | if (Integer.parseInt(lexer.peek()) != 0) { 63 | for (int i = 0; i < Integer.parseInt(lexer.peek()); i++) { 64 | orlist.add(tempor); 65 | delist.add(tempde); 66 | } 67 | } else { 68 | orlist.add(newnum1); 69 | delist.add(newnum0); 70 | } 71 | lexer.next(); 72 | } else { 73 | orlist.add(tempor); 74 | delist.add(tempde); 75 | } 76 | } 77 | 78 | public void getOtherFactor(ArrayList orlist, ArrayList delist) { 79 | Factor tempor; 80 | Factor tempde; 81 | Factor newnum = new Number(new BigInteger("-1")); 82 | Factor newnum1 = new Number(new BigInteger("1")); 83 | Factor newnum0 = new Number(new BigInteger("0")); 84 | while (lexer.peek().equals("*")) { 85 | lexer.next(); 86 | if (lexer.peek().equals("-")) { 87 | orlist.add(newnum); 88 | delist.add(newnum0); 89 | lexer.next(); 90 | } 91 | Lexer lexer1 = new Lexer(lexer); 92 | Parser parser = new Parser(lexer1); 93 | tempor = parser.parseFactor(); 94 | tempde = deFactor(); 95 | if (lexer.peek().equals("^")) { 96 | lexer.next(); 97 | if (Integer.parseInt(lexer.peek()) != 0) { 98 | for (int i = 0; i < Integer.parseInt(lexer.peek()); i++) { 99 | orlist.add(tempor); 100 | delist.add(tempde); 101 | } 102 | } else { 103 | orlist.add(newnum1); 104 | delist.add(newnum0); 105 | } 106 | lexer.next(); 107 | } else { 108 | orlist.add(tempor); 109 | delist.add(tempde); 110 | } 111 | } 112 | } 113 | 114 | public Factor deFactor() { 115 | if (lexer.peek().equals("(")) { 116 | return deExprFactor(); 117 | } else if (Character.isDigit(lexer.peek().charAt(0))) { 118 | return deNumFactor(); 119 | } else if ("fgh".indexOf(lexer.peek().charAt(0)) != -1) { 120 | return deFunFactor(); 121 | } else if (lexer.peek().equals("sin") || lexer.peek().equals("cos")) { 122 | return deTriFactor(); 123 | } else { 124 | return deVarFactor(); 125 | } 126 | } 127 | 128 | public void doubleNext() { 129 | lexer.next(); 130 | lexer.next(); 131 | } 132 | 133 | public Factor deExprFactor() { 134 | lexer.next(); 135 | Factor expr = deExpr(); 136 | lexer.next(); 137 | return expr; 138 | } 139 | 140 | public Factor deNumFactor() { 141 | BigInteger num = new BigInteger("0"); // fourth 142 | lexer.next(); 143 | return new Number(num); 144 | } 145 | 146 | public Factor deFunFactor() { 147 | Factor x; 148 | Factor y = null; 149 | Factor z = null; 150 | int count = 1; 151 | final String name = lexer.peek(); 152 | doubleNext(); 153 | Parser parser = new Parser(lexer); 154 | x = parser.parseExpr(); 155 | x = simplifyPara(x); 156 | while (lexer.peek().equals(",")) { 157 | lexer.next(); 158 | count++; 159 | if (count == 2) { 160 | y = parser.parseExpr(); 161 | y = simplifyPara(y); 162 | } else { 163 | z = parser.parseExpr(); 164 | z = simplifyPara(z); 165 | } 166 | } 167 | lexer.next(); 168 | Expr funexpr = MainClass.getFunction(name).calDefine(x, y, z); 169 | String str = funexpr.simplify(funexpr); 170 | str = str.replaceAll("\\*\\*", "^"); 171 | Lexer lexer1 = new Lexer(str); 172 | Derivative derivative = new Derivative("d" + para, lexer1); 173 | return derivative.deExpr(); 174 | } 175 | 176 | public Factor simplifyPara(Factor para) { 177 | Expr expr = (Expr) para; 178 | String str = expr.simplify(expr); 179 | str = str.replaceAll("\\*\\*", "^"); 180 | Lexer lexer1 = new Lexer(str); 181 | Parser parser = new Parser(lexer1); 182 | return parser.parseExpr(); 183 | } 184 | 185 | public Factor deTriFactor() { 186 | Factor circular; 187 | String tri = lexer.peek(); 188 | lexer.next(); 189 | Parser parser = new Parser(lexer); 190 | if (tri.equals("sin")) { 191 | circular = new DeSin(parser.parseExpr(), para); 192 | } else { 193 | circular = new DeCos(parser.parseExpr(), para); 194 | } 195 | lexer.next(); 196 | return circular; 197 | } 198 | 199 | public Factor deVarFactor() { 200 | Factor var; 201 | if (lexer.peek().equals(para)) { 202 | var = new DeVariable(lexer.peek()); 203 | } else { 204 | var = new Number(new BigInteger("0")); 205 | } 206 | lexer.next(); 207 | return var; 208 | } 209 | 210 | } 211 | -------------------------------------------------------------------------------- /hw3/Expr.java: -------------------------------------------------------------------------------- 1 | import java.math.BigInteger; 2 | import java.util.ArrayList; 3 | import java.util.HashMap; 4 | import java.util.Iterator; 5 | import java.util.TreeMap; 6 | 7 | public class Expr implements Factor { 8 | private final ArrayList terms; 9 | 10 | public Expr() { 11 | this.terms = new ArrayList<>(); 12 | } 13 | 14 | public void addTerm(Term term) { 15 | this.terms.add(term); 16 | } 17 | 18 | public String simplify(Expr expr) { 19 | HashMap finalexp = new HashMap<>(); 20 | finalexp.put("1", new BigInteger("0")); 21 | ArrayList doublesin = new ArrayList<>(); 22 | ArrayList> indexsin = new ArrayList<>(); 23 | ArrayList doublecos = new ArrayList<>(); 24 | ArrayList> indexcos = new ArrayList<>(); 25 | for (String s : getTerm(expr.toString())) { 26 | HashMap map = new HashMap<>(); 27 | getFactor(s, map); 28 | triMatchPro(doublesin, indexsin, doublecos, indexcos, map, finalexp); 29 | String term = joinMap(map); 30 | addFinal(term, map, finalexp); 31 | } 32 | return merge(finalexp); 33 | } 34 | 35 | public void triMatchPro(ArrayList doublesin, 36 | ArrayList> indexsin, 37 | ArrayList doublecos, 38 | ArrayList> indexcos, 39 | HashMap map, HashMap finalexp) { 40 | Iterator iterator = map.keySet().iterator(); 41 | while (iterator.hasNext()) { 42 | String next = iterator.next(); 43 | BigInteger index = map.get(next); 44 | if (next.startsWith("s") && index.compareTo(new BigInteger("2")) >= 0) { 45 | int temp = triMatch(doublecos, indexcos, map, next, finalexp); 46 | if (temp != 1) { 47 | if (!match(doublesin, indexsin, map, next)) { 48 | doublesin.add(next); 49 | indexsin.add(map); 50 | } 51 | } 52 | if (temp != 0) { 53 | triMatchPro(doublesin, indexsin, doublecos, indexcos, map, finalexp); 54 | } 55 | } else if (next.startsWith("c") && index.compareTo(new BigInteger("2")) >= 0) { 56 | int temp = triMatch(doublesin, indexsin, map, next, finalexp); 57 | if (temp != 1) { 58 | if (!match(doublecos, indexcos, map, next)) { 59 | doublecos.add(next); 60 | indexcos.add(map); 61 | } 62 | } 63 | if (temp != 0) { 64 | triMatchPro(doublesin, indexsin, doublecos, indexcos, map, finalexp); 65 | } 66 | } 67 | } 68 | } 69 | 70 | public void deepCopy(HashMap des, 71 | HashMap src) { 72 | for (String next : src.keySet()) { 73 | des.put(next, src.get(next)); 74 | } 75 | } 76 | 77 | public int triMatch(ArrayList name, ArrayList> index, 78 | HashMap maindex, String match, 79 | HashMap finalexp) { 80 | int flag = 0; 81 | for (int i = 0; i < name.size(); i++) { 82 | if (name.get(i).substring(3).equals(match.substring(3))) { 83 | if (triMapEqual(index.get(i), name.get(i), maindex, match)) { 84 | flag = 1; 85 | String change = joinMap(index.get(i)); 86 | if (finalexp.containsKey(change)) { 87 | if (finalexp.get(change).compareTo(maindex.get("1")) > 0) { 88 | finalexp.put(change, finalexp.get(change).subtract(maindex.get("1"))); 89 | maindex.put(match, maindex.get(match).subtract(new BigInteger("2"))); 90 | } else if (finalexp.get(change).compareTo(maindex.get("1")) < 0) { 91 | flag = 2; 92 | index.get(i).put(name.get(i), 93 | index.get(i).get(name.get(i)).subtract(new BigInteger("2"))); 94 | maindex.put("1", maindex.get("1").subtract(finalexp.get(change))); 95 | index.get(i).put("1", finalexp.get(change)); 96 | finalexp.remove(change); 97 | String newterm = joinMap(index.get(i)); 98 | addFinal(newterm, index.get(i), finalexp); 99 | name.remove(i); 100 | index.remove(i); 101 | break; 102 | } else { 103 | maindex.put(match, maindex.get(match).subtract(new BigInteger("2"))); 104 | index.get(i).put(name.get(i), 105 | index.get(i).get(name.get(i)).subtract(new BigInteger("2"))); 106 | finalexp.remove(change); 107 | name.remove(i); 108 | index.remove(i); 109 | break; 110 | } 111 | } else { 112 | flag = 0; 113 | break; 114 | } 115 | } 116 | } 117 | } 118 | return flag; 119 | } 120 | 121 | public boolean match(ArrayList name, ArrayList> index, 122 | HashMap maindex, String match) { 123 | boolean flag = false; 124 | for (int i = 0; i < name.size(); i++) { 125 | if (name.get(i).equals(match)) { 126 | if (triMapEqual(index.get(i), name.get(i), maindex, match)) { 127 | flag = true; 128 | } 129 | } 130 | } 131 | return flag; 132 | } 133 | 134 | public boolean triMapEqual(HashMap map1, String remove1, 135 | HashMap map2, String remove2) { 136 | HashMap cmap1 = new HashMap<>(); 137 | HashMap cmap2 = new HashMap<>(); 138 | for (String next : map1.keySet()) { 139 | cmap1.put(next, map1.get(next)); 140 | } 141 | for (String next : map2.keySet()) { 142 | cmap2.put(next, map2.get(next)); 143 | } 144 | cmap1.put(remove1, cmap1.get(remove1).subtract(new BigInteger("2"))); 145 | cmap2.put(remove2, cmap2.get(remove2).subtract(new BigInteger("2"))); 146 | return joinMap(cmap1).equals(joinMap(cmap2)); 147 | } 148 | 149 | public void addFinal(String term, HashMap map, 150 | HashMap finalexp) { 151 | if (map.size() > 1) { 152 | if (finalexp.containsKey(term)) { 153 | finalexp.put(term, finalexp.get(term).add(map.get("1"))); 154 | } else { 155 | finalexp.put(term, map.get("1")); 156 | } 157 | } else { 158 | finalexp.put("1", finalexp.get("1").add(map.get("1"))); 159 | } 160 | } 161 | 162 | public String joinMap(HashMap map) { 163 | StringBuilder sb = new StringBuilder(); 164 | int flag = 0; 165 | TreeMap sort = new TreeMap<>(map); 166 | for (String next : sort.keySet()) { 167 | if (map.get(next).equals(new BigInteger("0"))) { 168 | sb.append(""); 169 | } else if (!next.equals("1")) { 170 | if (flag == 1) { 171 | sb.append("*"); 172 | } 173 | flag = 1; 174 | sb = join(sb, map, next); 175 | } 176 | } 177 | if (sb.length() == 0) { 178 | sb.append("1"); 179 | } 180 | return sb.toString(); 181 | } 182 | 183 | public ArrayList getTerm(String exp) { 184 | ArrayList term = new ArrayList<>(); 185 | int last = 0; 186 | int count = 0; 187 | for (int i = 0; i < exp.length(); i++) { 188 | if (count == 0 && exp.charAt(i) == '+' && i > 0) { 189 | term.add(exp.substring(last, i)); 190 | last = i + 1; 191 | } else if (exp.charAt(i) == '(') { 192 | count--; 193 | } else if (exp.charAt(i) == ')') { 194 | count++; 195 | } 196 | } 197 | term.add(exp.substring(last)); 198 | return term; 199 | } 200 | 201 | public void getFactor(String s, HashMap map) { 202 | ArrayList factor = new ArrayList<>(); 203 | int last = 0; 204 | int count = 0; 205 | for (int i = 0; i < s.length(); i++) { 206 | if (count == 0 && s.charAt(i) == '*' && i > 0) { 207 | factor.add(s.substring(last, i)); 208 | last = i + 1; 209 | } else if (s.charAt(i) == '(') { 210 | count--; 211 | } else if (s.charAt(i) == ')') { 212 | count++; 213 | } 214 | } 215 | factor.add(s.substring(last)); 216 | map.put("1", new BigInteger("1")); 217 | for (String value : factor) { 218 | if ("xyzsc".indexOf(value.charAt(0)) != -1) { 219 | if (map.containsKey(value)) { 220 | map.put(value, map.get(value).add(new BigInteger("1"))); 221 | } else { 222 | map.put(value, new BigInteger("1")); 223 | } 224 | } else { 225 | map.put("1", map.get("1").multiply(new BigInteger(value))); 226 | } 227 | } 228 | } 229 | 230 | public StringBuilder join(StringBuilder sb, HashMap map, String str) { 231 | sb.append(str); 232 | if (!map.get(str).equals(new BigInteger("1"))) { 233 | if (map.get(str).equals(new BigInteger("2")) && "sc".indexOf(str.charAt(0)) == -1) { 234 | sb.append("*"); 235 | sb.append(str); 236 | } else { 237 | sb.append("**"); 238 | sb.append(map.get(str)); 239 | } 240 | } 241 | return sb; 242 | } 243 | 244 | public String merge(HashMap finalexp) { 245 | StringBuilder sb = new StringBuilder(); 246 | TreeMap sort = new TreeMap<>(finalexp); 247 | Iterator iterator = sort.keySet().iterator(); 248 | int flag = 0; 249 | while (iterator.hasNext()) { 250 | String next = iterator.next(); 251 | StringBuilder newsb = new StringBuilder(); 252 | if (next.equals("1")) { 253 | if (!finalexp.get(next).equals(new BigInteger("0"))) { 254 | if (finalexp.get(next).compareTo(new BigInteger("0")) > 0 && flag == 0) { 255 | newsb.append(finalexp.get(next)).append("+"); 256 | for (int m = 0; m < sb.length(); m++) { 257 | newsb.append(sb.charAt(m)); 258 | } 259 | sb = newsb; 260 | flag = 1; 261 | } else { 262 | sb.append(finalexp.get(next)).append("+"); 263 | } 264 | } 265 | } else { 266 | if (!finalexp.get(next).equals(new BigInteger("0"))) { 267 | if (finalexp.get(next).compareTo(new BigInteger("0")) > 0 && flag == 0) { 268 | if (!finalexp.get(next).equals(new BigInteger("1"))) { 269 | newsb.append(finalexp.get(next)).append("*"); 270 | } 271 | newsb.append(next).append("+"); 272 | for (int m = 0; m < sb.length(); m++) { 273 | newsb.append(sb.charAt(m)); 274 | } 275 | sb = newsb; 276 | flag = 1; 277 | } else { 278 | if (!finalexp.get(next).equals(new BigInteger("1"))) { 279 | if (!finalexp.get(next).equals(new BigInteger("-1"))) { 280 | sb.append(finalexp.get(next)).append("*"); 281 | } else { 282 | sb.append("-"); 283 | } 284 | } 285 | sb.append(next).append("+"); 286 | } 287 | } 288 | } 289 | } 290 | if (sb.toString().equals("")) { 291 | sb.append("0"); 292 | } 293 | if (sb.toString().endsWith("+")) { 294 | sb.deleteCharAt(sb.length() - 1); 295 | } 296 | String finalstr = sb.toString(); 297 | finalstr = finalstr.replaceAll("(-\\+)|(\\+-)", "-"); 298 | return finalstr; 299 | } 300 | 301 | public String reverse(String src) { 302 | int flag = 0; 303 | StringBuilder sb = new StringBuilder(); 304 | for (int i = 0; i < src.length(); i++) { 305 | if (flag == 0 && src.charAt(i) == '-') { 306 | if (i > 0) { 307 | sb.append("+"); 308 | } 309 | } else if (src.charAt(i) == '(') { 310 | sb.append("("); 311 | flag--; 312 | } else if (src.charAt(i) == ')') { 313 | sb.append(")"); 314 | flag++; 315 | } else { 316 | sb.append(src.charAt(i)); 317 | } 318 | } 319 | return sb.toString(); 320 | } 321 | 322 | public boolean isExprFactor(String str) { 323 | boolean flag = false; 324 | int count = 0; 325 | for (int i = 0; i < str.length(); i++) { 326 | if (count == 0 && ("+-*".indexOf(str.charAt(i)) != -1) && i > 0) { 327 | flag = true; 328 | return flag; 329 | } else if (str.charAt(i) == '(') { 330 | count--; 331 | } else if (str.charAt(i) == ')') { 332 | count++; 333 | } 334 | } 335 | return flag; 336 | } 337 | 338 | public String toString() { 339 | StringBuilder sb = new StringBuilder(); 340 | if (!terms.isEmpty()) { 341 | for (int i = 0; i < terms.size(); i++) { 342 | if (i > 0) { 343 | sb.append("+"); 344 | } 345 | sb.append(terms.get(i)); 346 | } 347 | } 348 | return sb.toString(); 349 | } 350 | } 351 | -------------------------------------------------------------------------------- /hw3/Factor.java: -------------------------------------------------------------------------------- 1 | public interface Factor { 2 | } 3 | -------------------------------------------------------------------------------- /hw3/Lexer.java: -------------------------------------------------------------------------------- 1 | public class Lexer { 2 | private final String input; 3 | private int pos = 0; 4 | private String curToken; 5 | 6 | public Lexer(String input) { 7 | this.input = input; 8 | this.next(); 9 | } 10 | 11 | public Lexer(Lexer lexer) { 12 | this.input = lexer.input; 13 | this.pos = lexer.pos; 14 | this.curToken = lexer.curToken; 15 | } 16 | 17 | private String getNumber() { 18 | StringBuilder sb = new StringBuilder(); 19 | while (pos < input.length() && Character.isDigit(input.charAt(pos))) { 20 | sb.append(input.charAt(pos)); 21 | ++pos; 22 | } 23 | 24 | return sb.toString(); 25 | } 26 | 27 | public void next() { 28 | if (pos == input.length()) { 29 | return; 30 | } 31 | char c = input.charAt(pos); 32 | if (Character.isDigit(c)) { 33 | curToken = getNumber(); // first 34 | } else if ("()+-*^,!@#<>?".indexOf(c) != -1) { // second 35 | pos += 1; 36 | curToken = String.valueOf(c); 37 | } else if (c == 's' || c == 'c') { 38 | pos += 4; 39 | if (c == 's') { 40 | curToken = "sin"; 41 | } else { 42 | curToken = "cos"; 43 | } 44 | } else if (c == 'd') { 45 | char next = input.charAt(pos + 1); 46 | pos += 3; 47 | if (next == 'x') { 48 | curToken = "dx"; 49 | } else if (next == 'y') { 50 | curToken = "dy"; 51 | } else { 52 | curToken = "dz"; 53 | } 54 | } else if (Character.isLetter(c)) { 55 | pos += 1; 56 | curToken = String.valueOf(c); 57 | } 58 | } 59 | 60 | public String peek() { 61 | return this.curToken; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /hw3/MainClass.java: -------------------------------------------------------------------------------- 1 | import java.util.Scanner; 2 | 3 | public class MainClass { 4 | private static SelfDefine functionF; 5 | private static SelfDefine functionG; 6 | private static SelfDefine functionH; 7 | 8 | public static SelfDefine getFunction(String name) { 9 | if (name.equals("f")) { 10 | return functionF; 11 | } else if (name.equals("g")) { 12 | return functionG; 13 | } else { 14 | return functionH; 15 | } 16 | } 17 | 18 | public static void iniFunction(String function) { 19 | if (function.startsWith("f")) { 20 | functionF = new SelfDefine(function); 21 | } else if (function.startsWith("g")) { 22 | functionG = new SelfDefine(function); 23 | } else if (function.startsWith("h")) { 24 | functionH = new SelfDefine(function); 25 | } 26 | } 27 | 28 | public static void main(String[] args) { 29 | Scanner scanner = new Scanner(System.in); 30 | String count = scanner.nextLine(); 31 | for (int i = 0; i < Integer.parseInt(count); i++) { 32 | String function = scanner.nextLine(); 33 | iniFunction(function); 34 | } 35 | String origin = scanner.nextLine(); 36 | StringSimplify st = new StringSimplify(origin); 37 | String expression = st.simplify(); 38 | Lexer lexer = new Lexer(expression); 39 | Parser parser = new Parser(lexer); 40 | 41 | Expr expr = parser.parseExpr(); 42 | System.out.println(expr.simplify(expr)); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /hw3/Number.java: -------------------------------------------------------------------------------- 1 | import java.math.BigInteger; 2 | 3 | public class Number implements Factor { 4 | private final BigInteger num; 5 | 6 | public Number(BigInteger num) { 7 | this.num = num; 8 | } 9 | 10 | public String toString() { 11 | return this.num.toString(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /hw3/Parser.java: -------------------------------------------------------------------------------- 1 | import java.math.BigInteger; 2 | 3 | public class Parser { 4 | private final Lexer lexer; 5 | private Factor x1; 6 | private Factor y1; 7 | private Factor z1; 8 | 9 | public Parser(Lexer lexer) { 10 | this.lexer = lexer; 11 | } 12 | 13 | public Parser(Lexer lexer, Factor x, Factor y, Factor z) { 14 | this.lexer = lexer; 15 | this.x1 = x; 16 | this.y1 = y; 17 | this.z1 = z; 18 | } 19 | 20 | public Expr parseExpr() { 21 | Expr expr = new Expr(); 22 | expr.addTerm(parseTerm()); 23 | 24 | while (lexer.peek().equals("+") || lexer.peek().equals("-")) { // first 25 | expr.addTerm(parseTerm()); 26 | } 27 | return expr; 28 | } 29 | 30 | public Term parseTerm() { 31 | Term term = new Term(); 32 | Factor temp; 33 | BigInteger num = new BigInteger("-1"); 34 | Factor newnum = new Number(num); 35 | BigInteger num1 = new BigInteger("1"); 36 | Factor newnum1 = new Number(num1); 37 | if (lexer.peek().equals("+")) { 38 | lexer.next(); 39 | temp = parseFactor(); 40 | } else if (lexer.peek().equals("-")) { 41 | term.addFactor(newnum); 42 | lexer.next(); 43 | temp = parseFactor(); 44 | } else { 45 | temp = parseFactor(); 46 | } 47 | if (lexer.peek().equals("^")) { 48 | lexer.next(); 49 | if (Integer.parseInt(lexer.peek()) != 0) { 50 | for (int i = 0; i < Integer.parseInt(lexer.peek()); i++) { 51 | term.addFactor(temp); 52 | } 53 | } else { 54 | term.addFactor(newnum1); 55 | } 56 | lexer.next(); 57 | } else { 58 | term.addFactor(temp); 59 | } 60 | while (lexer.peek().equals("*")) { 61 | lexer.next(); 62 | if (lexer.peek().equals("-")) { 63 | term.addFactor(newnum); 64 | lexer.next(); 65 | } 66 | temp = parseFactor(); 67 | if (lexer.peek().equals("^")) { 68 | lexer.next(); 69 | if (Integer.parseInt(lexer.peek()) != 0) { 70 | for (int i = 0; i < Integer.parseInt(lexer.peek()); i++) { 71 | term.addFactor(temp); 72 | } 73 | } else { 74 | term.addFactor(newnum1); 75 | } 76 | lexer.next(); 77 | } else { 78 | term.addFactor(temp); 79 | } 80 | } 81 | return term; 82 | } 83 | 84 | public Factor parseFactor() { 85 | if (lexer.peek().equals("(")) { 86 | return parseExprFactor(); 87 | } else if (lexer.peek().equals("-")) { 88 | doubleNext(); 89 | return new Number(new BigInteger("-1")); 90 | } else if (Character.isDigit(lexer.peek().charAt(0))) { 91 | return parseNumFactor(); 92 | } else if ("fgh".indexOf(lexer.peek().charAt(0)) != -1) { 93 | return parseFunFactor(); 94 | } else if ("!@#".indexOf(lexer.peek().charAt(0)) != -1) { 95 | return parseFunPara(); 96 | } else if (lexer.peek().equals("sin") || lexer.peek().equals("cos")) { 97 | return parseTriFactor(); 98 | } else if (lexer.peek().equals("dx") || lexer.peek().equals("dy") 99 | || lexer.peek().equals("dz")) { 100 | return parseDerFactor(); 101 | } else if ("<>?".indexOf(lexer.peek().charAt(0)) != -1) { 102 | return parseFunDe(); 103 | } else { 104 | return parseVarFactor(); 105 | } 106 | } 107 | 108 | public void doubleNext() { 109 | lexer.next(); 110 | lexer.next(); 111 | } 112 | 113 | public Factor parseFunFactor() { 114 | Factor x = null; 115 | Factor y = null; 116 | Factor z = null; 117 | int count = 1; 118 | final String name = lexer.peek(); 119 | doubleNext(); 120 | x = parseExpr(); 121 | x = simplifyPara(x); 122 | while (lexer.peek().equals(",")) { 123 | lexer.next(); 124 | count++; 125 | if (count == 2) { 126 | y = parseExpr(); 127 | y = simplifyPara(y); 128 | } else { 129 | z = parseExpr(); 130 | z = simplifyPara(z); 131 | } 132 | } 133 | lexer.next(); 134 | return MainClass.getFunction(name).calDefine(x, y, z); 135 | } 136 | 137 | public Factor simplifyPara(Factor para) { 138 | Expr expr = (Expr) para; 139 | String str = expr.simplify(expr); 140 | str = str.replaceAll("\\*\\*", "^"); 141 | Lexer lexer1 = new Lexer(str); 142 | Parser parser = new Parser(lexer1); 143 | return parser.parseExpr(); 144 | } 145 | 146 | public Factor parseFunPara() { 147 | if (lexer.peek().equals("!")) { 148 | lexer.next(); 149 | return x1; 150 | } else if (lexer.peek().equals("@")) { 151 | lexer.next(); 152 | return y1; 153 | } else { 154 | lexer.next(); 155 | return z1; 156 | } 157 | } 158 | 159 | public Factor parseTriFactor() { 160 | Factor circular; 161 | String tri = lexer.peek(); 162 | lexer.next(); 163 | if (tri.equals("sin")) { 164 | circular = new Sin(parseExpr()); 165 | } else { 166 | circular = new Cos(parseExpr()); 167 | } 168 | lexer.next(); 169 | return circular; 170 | } 171 | 172 | public Factor parseVarFactor() { 173 | Factor var = new Variable(lexer.peek()); 174 | lexer.next(); 175 | return var; 176 | } 177 | 178 | public Factor parseNumFactor() { 179 | BigInteger num = new BigInteger(lexer.peek()); // fourth 180 | lexer.next(); 181 | return new Number(num); 182 | } 183 | 184 | public Factor parseExprFactor() { 185 | lexer.next(); 186 | Factor expr = parseExpr(); 187 | lexer.next(); // third 188 | return expr; 189 | } 190 | 191 | public Factor parseDerFactor() { 192 | Derivative derivative; 193 | String name = lexer.peek(); 194 | lexer.next(); 195 | Expr der = parseExpr(); 196 | StringSimplify st = new StringSimplify(der.simplify(der)); 197 | String str = st.simplify(); 198 | Lexer lexer1 = new Lexer(str); 199 | derivative = new Derivative(name, lexer1); 200 | lexer.next(); 201 | return derivative.deExpr(); 202 | } 203 | 204 | public Factor parseFunDe() { 205 | Derivative derivative; 206 | String name; 207 | if (lexer.peek().equals("<")) { 208 | name = "dx"; 209 | } else if (lexer.peek().equals(">")) { 210 | name = "dy"; 211 | } else { 212 | name = "dz"; 213 | } 214 | lexer.next(); 215 | Expr der = parseExpr(); 216 | StringSimplify st = new StringSimplify(der.simplify(der)); 217 | String str = st.simplify(); 218 | Lexer lexer1 = new Lexer(str); 219 | derivative = new Derivative(name, lexer1); 220 | lexer.next(); 221 | String dered = derivative.deExpr().toString(); 222 | dered = dered.replaceAll("x", "!"); 223 | dered = dered.replaceAll("y", "@"); 224 | dered = dered.replaceAll("z", "#"); 225 | dered = dered.replaceAll("\\*\\*", "^"); 226 | Lexer lexer2 = new Lexer(dered); 227 | Parser parser = new Parser(lexer2, x1, y1, z1); 228 | return parser.parseExpr(); 229 | } 230 | } 231 | -------------------------------------------------------------------------------- /hw3/SelfDefine.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | 3 | public class SelfDefine implements Factor { 4 | private final String define; 5 | private final ArrayList para = new ArrayList<>(); 6 | 7 | public SelfDefine(String define) { 8 | StringSimplify st = new StringSimplify(define); 9 | String dispose = st.simplify(); 10 | String parameter = dispose.substring(0, dispose.indexOf('=')); 11 | for (int i = 0; i < parameter.length(); i++) { 12 | if ("xyz".indexOf(parameter.charAt(i)) != -1) { 13 | para.add(String.valueOf(parameter.charAt(i))); 14 | } 15 | } 16 | dispose = dispose.substring(dispose.indexOf('=') + 1); 17 | /*Lexer lexer = new Lexer(dispose); 18 | Parser parser = new Parser(lexer); 19 | Expr expr = parser.parseExpr(); 20 | dispose = expr.simplify(expr); 21 | dispose = dispose.replaceAll("\\*\\*","^");*/ 22 | int count = 0; 23 | StringBuilder sb = new StringBuilder(); 24 | for (int i = 0; i < dispose.length(); i++) { 25 | if (dispose.charAt(i) == 'd') { 26 | if (dispose.charAt(i + 1) == 'x') { 27 | sb.append("<"); 28 | } else if (dispose.charAt(i + 1) == 'y') { 29 | sb.append(">"); 30 | } else { 31 | sb.append("?"); 32 | } 33 | count--; 34 | i += 2; 35 | } else if (dispose.charAt(i) == '(' && count < 0) { 36 | sb.append("("); 37 | count--; 38 | } else if (dispose.charAt(i) == ')' && count < 0) { 39 | sb.append(")"); 40 | count++; 41 | } else if (dispose.charAt(i) == 'x' && count == 0) { 42 | sb.append("!"); 43 | } else if (dispose.charAt(i) == 'y' && count == 0) { 44 | sb.append("@"); 45 | } else if (dispose.charAt(i) == 'z' && count == 0) { 46 | sb.append("#"); 47 | } else { 48 | sb.append(dispose.charAt(i)); 49 | } 50 | } 51 | /*dispose = dispose.replaceAll("x", "!"); 52 | dispose = dispose.replaceAll("y", "@"); 53 | dispose = dispose.replaceAll("z", "#");*/ 54 | this.define = sb.toString(); 55 | } 56 | 57 | public Expr calDefine(Factor x, Factor y, Factor z) { 58 | Lexer lexer; 59 | Factor a = null; 60 | Factor b = null; 61 | Factor c = null; 62 | lexer = new Lexer(define); 63 | for (int i = 0; i < para.size(); i++) { 64 | Factor temp; 65 | temp = temp(i, x, y, z); 66 | if (para.get(i).equals("x")) { 67 | a = temp; 68 | } else if (para.get(i).equals("y")) { 69 | b = temp; 70 | } else if (para.get(i).equals("z")) { 71 | c = temp; 72 | } 73 | } 74 | Parser parser = new Parser(lexer, a, b, c); 75 | return parser.parseExpr(); 76 | } 77 | 78 | public Factor temp(int i, Factor x, Factor y, Factor z) { 79 | if (i == 0) { 80 | return x; 81 | } else if (i == 1) { 82 | return y; 83 | } else { 84 | return z; 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /hw3/Sin.java: -------------------------------------------------------------------------------- 1 | public class Sin implements Factor { 2 | private final Expr expression; 3 | 4 | public Sin(Expr expression) { 5 | this.expression = expression; 6 | } 7 | 8 | public String toString() { 9 | String temp = expression.simplify(expression); 10 | if (temp.equals("0")) { 11 | return "0"; 12 | } else { 13 | String str; 14 | String temp1 = temp.replaceAll("\\*\\*", "^"); 15 | if (expression.isExprFactor(temp1)) { 16 | if (temp1.startsWith("-")) { 17 | str = "-1*sin((" + expression.reverse(temp) + "))"; 18 | } else { 19 | str = "sin((" + temp + "))"; 20 | } 21 | } else { 22 | if (temp1.startsWith("-")) { 23 | str = "-1*sin(" + expression.reverse(temp) + ")"; 24 | } else { 25 | str = "sin(" + temp + ")"; 26 | } 27 | } 28 | return str; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /hw3/StringSimplify.java: -------------------------------------------------------------------------------- 1 | public class StringSimplify { 2 | private final String origin; 3 | 4 | public StringSimplify(String origin) { 5 | this.origin = origin; 6 | } 7 | 8 | public String simplify() { 9 | String expression = origin.replaceAll("[ \t]", ""); 10 | expression = expression.replaceAll("\\(\\+", "("); 11 | expression = expression.replaceAll("(\\+\\+)|(--)", "+"); 12 | expression = expression.replaceAll("\\*\\*", "^"); 13 | expression = expression.replaceAll("(-\\+)|(\\+-)", "-"); 14 | expression = expression.replaceAll("\\^\\+", "^"); 15 | expression = expression.replaceAll("\\*\\+", "*"); 16 | expression = expression.replaceAll("^\\+", ""); 17 | expression = expression.replaceAll("(\\+\\+)|(--)", "+"); 18 | expression = expression.replaceAll("(-\\+)|(\\+-)", "-"); 19 | expression = expression.replaceAll("^\\+", ""); 20 | return expression; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /hw3/Term.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | 3 | public class Term implements Factor { 4 | private final ArrayList factors; 5 | 6 | public Term() { 7 | this.factors = new ArrayList<>(); 8 | } 9 | 10 | public void addFactor(Factor factor) { 11 | organizeFactor(factor); 12 | } 13 | 14 | public void organizeFactor(Factor factor) { 15 | Factor add = new Variable("+"); 16 | ArrayList newfactors = new ArrayList<>(); 17 | ArrayList newterms = new ArrayList<>(); 18 | if (isExpr(factor)) { 19 | newterms = getNewTerms(factor); 20 | if (!factors.isEmpty()) { 21 | for (int i = 0; i < newterms.size(); i++) { 22 | int flag = 0; 23 | for (Factor value : factors) { 24 | if (!value.toString().equals("+")) { 25 | if (flag == 0) { 26 | newfactors.add(newterms.get(i)); 27 | flag = 1; 28 | } 29 | newfactors.add(value); 30 | } else { 31 | flag = 0; 32 | newfactors.add(add); 33 | } 34 | } 35 | if (i < newterms.size() - 1) { 36 | newfactors.add(add); 37 | } 38 | } 39 | } else { 40 | for (int i = 0; i < newterms.size(); i++) { 41 | newfactors.add(newterms.get(i)); 42 | if (i < newterms.size() - 1) { 43 | newfactors.add(add); 44 | } 45 | } 46 | } 47 | } else { 48 | if (!factors.isEmpty()) { 49 | int flag = 0; 50 | for (Factor value : factors) { 51 | if (!value.toString().equals("+")) { 52 | if (flag == 0) { 53 | newfactors.add(factor); 54 | flag = 1; 55 | } 56 | newfactors.add(value); 57 | } else { 58 | flag = 0; 59 | newfactors.add(add); 60 | } 61 | } 62 | } else { 63 | newfactors.add(factor); 64 | } 65 | } 66 | factors.clear(); 67 | factors.addAll(newfactors); 68 | } 69 | 70 | public ArrayList getNewTerms(Factor factor) { 71 | ArrayList term = new ArrayList<>(); 72 | String temp = factor.toString().replaceAll("\\*\\*", "^"); 73 | Lexer le = new Lexer(temp); 74 | Parser pa = new Parser(le); 75 | term.add(pa.parseTerm()); 76 | while (le.peek().equals("+")) { 77 | le.next(); 78 | term.add(pa.parseTerm()); 79 | } 80 | return term; 81 | } 82 | 83 | public boolean isExpr(Factor factor) { 84 | String str = factor.toString(); 85 | boolean flag = false; 86 | int count = 0; 87 | for (int i = 0; i < str.length(); i++) { 88 | if (count == 0 && str.charAt(i) == '+' && i > 0) { 89 | flag = true; 90 | return flag; 91 | } else if (str.charAt(i) == '(') { 92 | count--; 93 | } else if (str.charAt(i) == ')') { 94 | count++; 95 | } 96 | } 97 | return flag; 98 | } 99 | 100 | public void multiTerm(ArrayList orlist, ArrayList delist) { 101 | Factor add = new Variable("&"); 102 | for (int i = 0; i < delist.size(); i++) { 103 | Term newterm = new Term(); 104 | newterm.addFactor(delist.get(i)); 105 | for (int j = 0; j < orlist.size(); j++) { 106 | if (j != i) { 107 | newterm.addFactor(orlist.get(j)); 108 | } 109 | } 110 | factors.add(newterm); 111 | if (i < delist.size() - 1) { 112 | factors.add(add); 113 | } 114 | } 115 | } 116 | 117 | public String toString() { 118 | StringBuilder sb = new StringBuilder(); 119 | int flag1 = 0; 120 | if (!factors.isEmpty()) { 121 | for (int i = 0; i < factors.size(); i++) { 122 | if (factors.get(i).toString().equals("+") || 123 | factors.get(i).toString().equals("&")) { 124 | sb.append("+"); 125 | flag1 = 1; 126 | } else { 127 | if (i > 0 && flag1 == 0) { 128 | sb.append("*"); 129 | } 130 | sb.append(factors.get(i).toString()); 131 | flag1 = 0; 132 | } 133 | } 134 | } 135 | return sb.toString(); 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /hw3/Variable.java: -------------------------------------------------------------------------------- 1 | public class Variable implements Factor { 2 | private final String var; 3 | 4 | public Variable(String var) { 5 | this.var = var; 6 | } 7 | 8 | public String toString() { 9 | return var; 10 | } 11 | } 12 | --------------------------------------------------------------------------------