一、前言
PTA 上三套数字电路作业全部完成虽然还是没有完全通过测试点,三次作业以基础逻辑门→单层电路→多层嵌套子电路仿真的顺序逐步拓展,难度持续提升,需要用到的 Java 面向对象、文本解析、循环迭代、异常处理知识点越来越多,整套程序完整走通后收获很大。
第一次作业属于入门基础练习,题型单一,难度最低,主要用来上手熟悉抽象类、继承、集合容器、简单字符串分割、基础排序这些课堂基础内容,把五种逻辑门用面向对象思路封装起来,只处理单层输入输出,实操巩固基础语法。
第二次作业在第一版基础上新增子电路解析模块,区分顶层全局信号与子电路内部端口,新增端口绑定、多电路隔离逻辑,数据校验代码同步增加,代码量与逻辑思考量明显上涨,重点练习多类之间的协同调用、业务代码拆分。
第三次是完整工程版本,整合前两次全部功能,新增五级优先级异常拦截、循环迭代信号传播、标准化分类输出,还借助自定义异常、正则匹配完善语法解析。
三次作业不是简单拼接代码应付提交,而是从实体类搭建、基础运算实现,再扩充业务边界、优化代码结构,完整走完小型仿真解释器从 0 到 1 的开发流程,不管代码编写手感还是逻辑拆解思考方式,都比刚开始进步很多。
二、设计与分析

第一次作业整体类结构简单,业务逻辑直白,一共 5 个核心类。抽象父类 BaseGate 封装门通用属性与运算抽象方法,And、Or、Not、Xor、Xnor 五个子类分别实现对应数字逻辑;Connection 存储单条连线文本;Main 主类统一调度输入、解析、运算、打印。
编码时严格遵循封装思想,所有成员变量全部私有化,只提供 get/set 访问方法,外部无法直接修改内部数据。整套代码没有复杂嵌套循环,分支判断很少,只用 ArrayList 存储输入信号、门对象,正则仅简单匹配门名称。
从代码度量工具数据来看,第一次代码总行数偏少,每个方法语句简短,圈复杂度极低,调试、改错都很轻松。但短板十分明显:仅支持单层电路,无独立子电路空间,缺少各类非法输入校验,一旦出现引脚重复、顺序颠倒等数据,程序直接异常崩溃,只能完成理想状态下的基础运算,离规范仿真程序差距很大。

有了第一次单层电路的开发经验,第二版我刻意拆分功能,不再把所有逻辑堆砌在主函数。新增 SubCircuit 子电路独立类,每个子电路单独存储输入端口、输出端口、内部连线、门集合、端口电平,实现多套电路信号互不干扰;新增全局信号绑定逻辑,支持顶层输入映射到子电路 IN 端口;新增基础重复引脚冲突检测工具代码。
航班作业是分货舱,这里是分电路,思路相通,每个子电路拥有独立数据空间,不会出现电平串扰。调度逻辑拆分多个独立方法,读取文本、解析子块、绑定信号分开写,主方法只负责流程串联,不会出现几百行臃肿代码。
代码规模明显增加,类数量同步上涨,少数端口赋值、连线校验方法存在多层 if 嵌套,阅读起来稍微繁琐,但所有功能高度内聚,修改某一块电路逻辑不会影响其他模块,模块化开发的优势体现出来。

第三套是完整可商用仿真版本,整合前两版所有功能,补齐全部边界处理逻辑,也是耗时最长的一次作业。
第一,新增五级优先级异常校验,严格按照题目规定顺序判断多输出、无输出、顺序颠倒、无输入、引脚冲突五类错误,匹配 PTA 异常测试样例;第二,优化信号传递机制,改用 do-while 循环迭代刷新电平,解决多层子电路单次遍历数值传递不全、输出空白问题;第三,完善自定义报错提示,出现非法连线直接打印题目指定文字,程序友好终止,不会闪退;第四,增加输出排序规则,强制先打印子电路门,再打印顶层门,同一类型按编号升序输出。
架构层面大幅重构,抽离 CircuitCore 调度类,把输入读取、分词解析、信号迭代、批量运算、打印全部拆分为独立私有方法,实体类只负责存储数据,运算、解析逻辑全部抽离工具方法,分层清晰。
优化后剔除大量冗余重复代码,多层 if 嵌套大幅精简,每个方法只承担单一功能,整套程序覆盖正常运算、各类非法输入、多层嵌套子电路、多组独立电路全部场景,流程通顺完整,但个别样例仍无法通过。
三、踩坑心得
第一次作业踩坑
- 直接操作原始门集合排序,排序后原始数据顺序被打乱,后续取值、统计全部出错。后来新建临时集合复制数据,对副本排序,原始数据源保持不变,才解决统计错乱问题,要记得不要直接修改原始存储容器。
- 门输出值不会自动更新,新增输入后忘记重新调用 calculate () 计算,打印结果永远是初始 null。之后每次引脚赋值都同步触发运算,保证输出实时刷新。
- Scanner 连续读取文本时残留换行符,导致分词为空字符串,解析连线时报错,后续每次读取后吸收多余换行,规避空文本解析异常。
第二次作业踩坑
- 连线判断逻辑顺序写反,先添加门引脚再判断剩余容量,出现超载重分配。纠正为先校验剩余电平空间,满足条件再绑定信号,贴合真实电路装载逻辑。
- 跨类直接访问私有成员变量,编译报错且代码耦合严重,统一改用 getter 方法传递数值,代码规范度提升,报错减少。
第三次作业踩坑
- 异常判断优先级颠倒,样例 6 输入[A(2)1-1 A],本该提示顺序错误,程序误判无输出。重新按照题目规定顺序:先统计所有不带 “-” 输出源,再依次判断数量、位置、引脚冲突,所有异常用例输出完全匹配 PTA 标准答案。
- 仅单次循环传递电平,多层子电路输出端口依赖内部门运算,第一轮无有效数值,所有子电路用例打印空白。改用循环迭代,一轮有数值变动就重新遍历所有连线,直到电平稳定不变。
- 门创建正则分组下标写错,N、X、Y 门无法实例化,对应运算全部为空。修正正则 group 读取下标,五类门都能正常创建参与运算。
- 输出未分类乱序打印,判题扣分。新增五个独立列表分别存放五类门,统一用编号升序排序,先输出子电路再输出顶层门,格式符合题目要求。
- 只测试正常输入,忽略无端口、多引脚绑定、空电路等边界用例,提交大量隐藏测试点报错,后期补充各类极端场景反复测试,补齐部分判断分支。
四、改进建议
结合三次代码度量报表、类图结构、PTA 所有测试用例运行情况,现有程序基础功能基本可用,但仍有大量优化空间。



- 代码结构优化:当前 createGate 方法大量 if-else 匹配门名称,后续拓展多路选择器、触发器等元件会持续堆叠分支。引入工厂模式,用映射表存储正则与对应门构造器,新增元件无需修改判断代码。
- 异常体系优化:目前依靠全局 errorFlag 标记错误,每层方法都要判断标记。自定义电路语法、引脚冲突细分异常,出错直接 throw,主调度统一捕获打印,消除全局状态变量,简化分支。
- 性能优化:信号迭代每次全量遍历所有连线,大型多层电路存在无效循环。新增变更节点集合,只遍历电平发生变化的端口,减少 Map 重复遍历,提升仿真速度。
- 代码规范优化:整套代码几乎无注释,时隔一段时间很难看懂核心迭代、校验逻辑。
五、总结
三套数字电路仿真作业迭代完成,不再单纯死记 Java 理论,真正把抽象类、继承、多态、文本解析、循环迭代、异常处理全部落地小型解释器项目。
第一,吃透面向对象核心思想:通过五类门继承、三类信号多态、子电路独立封装,学会用分层、抽象拆分复杂业务,不用堆砌几百行流程代码,高内聚低耦合能极大减少 bug。
第二,边界与异常是得分关键,之前只跑正常用例大量隐藏测试点失分,现在开发完必须覆盖多输出、顺序颠倒、引脚重复、空电路等所有非法场景,严格按照需求优先级写判断逻辑,细微文字、顺序偏差都会判错。
第三,动态数据不能用单次静态遍历,电路电平互相依赖,单次扫描无法传递多层数值,循环迭代更新才符合真实电路工作逻辑,这是本次开发最大收获之一。
第四,工程规范硬性要求不可忽视,输出文字、报错语句、打印顺序、符号分隔必须和样例一字不差,自主简化逻辑极易扣分。
自身短板也十分清晰:编译原理基础薄弱,分词解析手写逻辑冗余;各类设计模式只懂理论,没有大规模落地;仅支持组合逻辑,时序电路拓展能力不足。
后续会按照优化方案重构代码,落地工厂模式、自定义异常,补充注释与批量测试功能,拓展时序触发器仿真。
整体三次作业完整走完小型程序开发全流程,从需求拆解、写类图、编码、调试、代码质量分析一整套实操,编程思路、排错能力都有明显提升,后续会继续夯实 Java 基础,规范编码习惯,积累项目开发经验。
