302
社区成员
发帖
与我相关
我的任务
分享| Class | OCavg | OCmax | WMC |
|---|---|---|---|
| ExpandedExpr | 2.93 | 7 | 44 |
| ExprFormatter | 4.22 | 9 | 38 |
| FunctionDef | 1.00 | 1 | 4 |
| FunctionDefParser | 2.50 | 4 | 5 |
| FunctionTable | 1.25 | 2 | 5 |
| Main | 2.00 | 2 | 2 |
| MonoKey | 1.93 | 4 | 27 |
| Parser | 3.23 | 6 | 42 |
| Simplifier | 2.70 | 9 | 27 |
| Substitute | 6.00 | 10 | 12 |
| element.AddExpr | 1.00 | 1 | 3 |
| element.ConditionalExpr | 1.00 | 1 | 5 |
| element.ExpExpr | 1.00 | 1 | 2 |
| element.FunctionCallExpr | 1.00 | 1 | 3 |
| element.MulExpr | 1.00 | 1 | 3 |
| element.NumberExpr | 1.00 | 1 | 2 |
| element.PowExpr | 1.00 | 1 | 3 |
| element.VariableExpr | 1.00 | 1 | 2 |
| Method | CogC | ev(G) | iv(G) | v(G) |
|---|---|---|---|---|
| ExpandedExpr.ExpandedExpr() | 0 | 1 | 1 | 1 |
| ExpandedExpr.ExpandedExpr(HashMap<MonoKey, BigInteger>) | 3 | 1 | 3 | 3 |
| ExpandedExpr.add(ExpandedExpr) | 11 | 1 | 5 | 5 |
| ExpandedExpr.appendTerm(StringBuilder, BigInteger, MonoKey) | 4 | 2 | 4 | 4 |
| ExpandedExpr.compareMonoKey(MonoKey, MonoKey) | 1 | 2 | 1 | 2 |
| ExpandedExpr.constant(BigInteger) | 1 | 1 | 2 | 2 |
| ExpandedExpr.expAtom(String, BigInteger) | 2 | 3 | 2 | 3 |
| ExpandedExpr.isZero() | 0 | 1 | 1 | 1 |
| ExpandedExpr.multiply(ExpandedExpr) | 16 | 1 | 6 | 6 |
| ExpandedExpr.negate() | 1 | 1 | 2 | 2 |
| ExpandedExpr.one() | 0 | 1 | 1 | 1 |
| ExpandedExpr.pow(BigInteger) | 5 | 3 | 4 | 5 |
| ExpandedExpr.toCanonicalString() | 12 | 5 | 4 | 7 |
| ExpandedExpr.toString() | 0 | 1 | 1 | 1 |
| ExpandedExpr.variable() | 0 | 1 | 1 | 1 |
| ExprFormatter.ExprFormatter() | 0 | 1 | 1 | 1 |
| ExprFormatter.findMatchingRightParenthesis(String, int) | 9 | 6 | 4 | 8 |
| ExprFormatter.formatAsExpArgument(ExpandedExpr) | 2 | 2 | 1 | 2 |
| ExprFormatter.formatAsExpr(ExpandedExpr) | 0 | 1 | 1 | 1 |
| ExprFormatter.isInteger(String) | 7 | 6 | 3 | 6 |
| ExprFormatter.isPurePowerOfX(String) | 6 | 6 | 2 | 6 |
| ExprFormatter.isSimpleAtom(String) | 3 | 4 | 1 | 4 |
| ExprFormatter.isSingleExpAtom(String) | 9 | 9 | 2 | 9 |
| ExprFormatter.needsParenthesesInExpArgument(ExpandedExpr, String) | 2 | 3 | 1 | 3 |
| FunctionDef.FunctionDef(String, List, Expr) | 0 | 1 | 1 | 1 |
| FunctionDef.getBody() | 0 | 1 | 1 | 1 |
| FunctionDef.getFunctionName() | 0 | 1 | 1 | 1 |
| FunctionDef.getParameters() | 0 | 1 | 1 | 1 |
| FunctionDefParser.parse(String) | 4 | 3 | 2 | 6 |
| FunctionDefParser.removeSpaces(String) | 0 | 1 | 1 | 1 |
| FunctionTable.FunctionTable() | 0 | 1 | 1 | 1 |
| FunctionTable.addFunction(FunctionDef) | 0 | 1 | 1 | 1 |
| FunctionTable.contains(String) | 0 | 1 | 1 | 1 |
| FunctionTable.getFunction(String) | 1 | 2 | 1 | 2 |
| Main.main(String[]) | 1 | 1 | 2 | 2 |
| MonoKey.MonoKey() | 0 | 1 | 1 | 1 |
| MonoKey.MonoKey(BigInteger, TreeMap<String, BigInteger>) | 3 | 1 | 3 | 3 |
| MonoKey.appendExp(StringBuilder, String, BigInteger) | 1 | 1 | 2 | 2 |
| MonoKey.appendX(StringBuilder, BigInteger) | 1 | 1 | 2 | 2 |
| MonoKey.equals(Object) | 3 | 3 | 2 | 4 |
| MonoKey.expFactor(String, BigInteger) | 1 | 1 | 2 | 2 |
| MonoKey.getExpFactors() | 0 | 1 | 1 | 1 |
| MonoKey.getXExponent() | 0 | 1 | 1 | 1 |
| MonoKey.hashCode() | 0 | 1 | 1 | 1 |
| MonoKey.isOne() | 1 | 1 | 2 | 2 |
| MonoKey.multiply(MonoKey) | 8 | 1 | 4 | 4 |
| MonoKey.one() | 0 | 1 | 1 | 1 |
| MonoKey.toFactorString() | 4 | 1 | 4 | 4 |
| MonoKey.variable() | 0 | 1 | 1 | 1 |
| Parser.Parser(String) | 0 | 1 | 1 | 1 |
| Parser.parse() | 1 | 2 | 1 | 2 |
| Parser.parseAtomicFactor() | 3 | 4 | 4 | 4 |
| Parser.parseConditionalFactor() | 0 | 1 | 1 | 1 |
| Parser.parseExpression() | 5 | 4 | 4 | 4 |
| Parser.parseFactor() | 7 | 5 | 5 | 5 |
| Parser.parseFunctionCallAfterName(String) | 11 | 6 | 7 | 10 |
| Parser.parseIdentifier() | 4 | 2 | 3 | 5 |
| Parser.parseIdentifierBasedFactor() | 11 | 6 | 8 | 11 |
| Parser.parsePower() | 5 | 2 | 4 | 5 |
| Parser.parseTerm() | 2 | 1 | 3 | 3 |
| Parser.parseUnsignedInteger() | 3 | 2 | 2 | 4 |
| Parser.skipSpaces() | 2 | 1 | 2 | 3 |
| Simplifier.Simplifier(FunctionTable) | 0 | 1 | 1 | 1 |
| Simplifier.simplify(Expr) | 8 | 9 | 9 | 9 |
| Simplifier.simplifyAdd(AddExpr) | 0 | 1 | 1 | 1 |
| Simplifier.simplifyConditional(ConditionalExpr) | 2 | 2 | 2 | 2 |
| Simplifier.simplifyExp(ExpExpr) | 1 | 2 | 2 | 2 |
| Simplifier.simplifyFunctionCall(FunctionCallExpr) | 2 | 2 | 3 | 3 |
| Simplifier.simplifyMul(MulExpr) | 4 | 3 | 7 | 7 |
| Simplifier.simplifyNumber(NumberExpr) | 0 | 1 | 1 | 1 |
| Simplifier.simplifyPow(PowExpr) | 4 | 2 | 4 | 4 |
| Simplifier.simplifyVariable(VariableExpr) | 1 | 2 | 2 | 2 |
| Substitute.substitute(Expr, Map<String, Expr>) | 21 | 9 | 9 | 10 |
| Substitute.substituteVariable(VariableExpr, Map<String, Expr>) | 1 | 2 | 1 | 2 |
| element.AddExpr.AddExpr(Expr, Expr) | 0 | 1 | 1 | 1 |
| element.AddExpr.getLeft() | 0 | 1 | 1 | 1 |
| element.AddExpr.getRight() | 0 | 1 | 1 | 1 |
| element.ConditionalExpr.ConditionalExpr(Expr, Expr, Expr, Expr) | 0 | 1 | 1 | 1 |
| element.ConditionalExpr.getFalseBranch() | 0 | 1 | 1 | 1 |
| element.ConditionalExpr.getLeftFactor() | 0 | 1 | 1 | 1 |
| element.ConditionalExpr.getRightFactor() | 0 | 1 | 1 | 1 |
| element.ConditionalExpr.getTrueBranch() | 0 | 1 | 1 | 1 |
| element.ExpExpr.ExpExpr(Expr) | 0 | 1 | 1 | 1 |
| element.ExpExpr.getArgument() | 0 | 1 | 1 | 1 |
| element.FunctionCallExpr.FunctionCallExpr(String, List) | 0 | 1 | 1 | 1 |
| element.FunctionCallExpr.getArguments() | 0 | 1 | 1 | 1 |
| element.FunctionCallExpr.getFunctionName() | 0 | 1 | 1 | 1 |
| element.MulExpr.MulExpr(Expr, Expr) | 0 | 1 | 1 | 1 |
| element.MulExpr.getLeft() | 0 | 1 | 1 | 1 |
| element.MulExpr.getRight() | 0 | 1 | 1 | 1 |
| element.NumberExpr.NumberExpr(BigInteger) | 0 | 1 | 1 | 1 |
| element.NumberExpr.getValue() | 0 | 1 | 1 | 1 |
| element.PowExpr.PowExpr(Expr, BigInteger) | 0 | 1 | 1 | 1 |
| element.PowExpr.getBase() | 0 | 1 | 1 | 1 |
| element.PowExpr.getExponent() | 0 | 1 | 1 | 1 |
| element.VariableExpr.VariableExpr(String) | 0 | 1 | 1 | 1 |
| element.VariableExpr.getName() | 0 | 1 | 1 | 1 |

Parser
负责将输入字符串解析为 AST。尽管 Parser 类的 WMC 和 OCavg 都相对较高,但这是由于所有(非函数调用)语法解析逻辑都集中在该类中完成。这样的设计使解析过程统一管理,避免解析逻辑分散在多个类中,从而保证了解析模块的高内聚。同时,解析阶段仅负责构建 AST,不涉及表达式化简,从而实现了解析与语义处理的解耦。
element 包中的各类
element 包中的类用于表示 AST 的不同节点类。这些类只负责描述表达式结构,而不包含复杂的运算逻辑。Parser 在解析过程中构建这些节点对象,而后续的化简逻辑由 Simplifier 处理。
Simplifier
Simplifier 是表达式语义简化的核心类。在第一次作业中,该类主要负责对 AST 表达式进行基本的代数化简与合并同类项;在第二次作业中,其功能进一步扩展,同时负责处理新增的选择式结构以及辅助进行函数调用等。Simplifier 通过递归遍历 AST,将表达式转换为统一的规范表示。
ExpandedExpr
ExpandedExpr 用于表示化简后的表达式结构,是 Simplifier 输出结果的统一表示形式。其内部使用 HashMap<MonoKey, BigInteger> 存储表达式中的各个项,实现了同类项合并和代数运算。
FunctionDefParser
FunctionDefParser 用于解析输入中的函数定义语句。该类负责提取函数名、形参以及函数体表达式,并构造 FunctionDef 对象存储解析结果。通过将函数定义解析逻辑单独封装在该类中,可以避免函数处理逻辑混入主表达式解析流程,从而提高 OO 程度。
总体来说,就是解析与化简分开,函数解析与表达式解析分开。
建立了 Main -> Lexer/Parse -> (AST) -> Simplifier -> Monokey 解析/化简流程,最后输出 Monokey 的哈希表作为化简出的多项式结果。
因为最后输出的项变得更复杂了,还要考虑提 gcd,所以在 Simplifier -> Monokey 的化简流程中加了 ExpandedExpr,ExpandedExpr 类在内部实现了提形如 exp((...)) 因子的 gcd。
同时,为支持函数调用,在表达式解析流程之外加了函数解析类 FunctionDefParser 和形参替换类 Substitute,处理表达式解析类 Parser 输出的 AST。
没做出来。
没有进行重构
幂次爆 int
错误原因:幂次没有范围
解决方法:全开 BigInteger
不能识别形如 -+<数字> 的格式
错误原因:解析具有连续 +/- 时 Parse 遇到困难
解决方法:首先扫描一遍输入表达式字符串,遇到连续 +/- 只保留一个
遇到形如 x^+<数字> 格式报错
错误原因;第二次作业重写了解析幂次的 Parse 方法,改错了
解决方法:首先扫描一遍输入表达式字符串,不必要的 + 号删掉
利用选择式的 Cost 规则,在未选择的的选择式分支插大量的递归,引起 TLE。
用上次作业的 bug 构造测试案例,先在本地对别人的代码跑一遍,如果依然出现 bug 则提交。
结合被测程序的代码设计结构来设计测试用例,特别寻找可以构建 TLE 的代码结构。
做了提 gcd 优化,可以保证代码的简洁性与正确性。首先,耗时不长,不会 TLE。其次,由于表达式解析和化简在一个流程中解耦进行,所以可以直接在 Simplifier 类和 Monokey 类中插入一个专门类负责提 gcd 等。
使用了大模型提供提 gcd 优化思路,完成效果很好。
第一次作业到第二次作业难度跨度太大。
第二次作业可以像第一次/第三次作业那样,有类似实验课提供思路。