BLOG-2
OOP题目集4
NCHUD-数字电路模拟程序-1
数字电路是一种处理离散信号的电子电路。与处理连续变化信号(如声音、温度)的模拟电路不同,数字电路只识别和运算两种基本状态:高电平(通常表示为“1”) 和 低电平(通常表示为“0”)。这正好与二进制数制系统相对应,使得数字电路成为所有计算机和数字系统的物理实现基础。
请编程实现数字电路模拟程序,
1、电路元件
电路中包含与门、或门、非门、异或门、同或门五种元件。元件特征如下:
与门:image.png
包含两个或多个输入引脚和一个输出引脚。所有输入引脚必须都是高电平,输出引脚才是高电平,只要有一个输入引脚为低电平,输出引脚输出低电平。
或门:
image.png
包含两个或多个输入引脚和一个输出引脚。所有输入引脚必须都是低电平,输出引脚才是低电平,只要有一个输入引脚为高电平,输出引脚输出高电平。
非门:
image.png
包含一个输入引脚和一个输出引脚。输出引脚的电平与输入引脚的电平相反,如输入为低电平,输出则为高电平。
异或门:
image.png
包含两个输入引脚和一个输出引脚。当两个输入引脚电平不一致时输出引脚输出高电平,否则输出低电平。
同或门:
image.png包含两个输入引脚和一个输出引脚。当两个输入引脚电平一致时输出引脚输出高电平,否则输出低电平。
2、程序输入
1)元件信息:
用A、O、N、X、Y 分别用作与门、或门、非门、异或门、同或门五种元件的元件标识符。
电路中的每个与门、或门用“标识符(输入引脚数)+编号”作为其元件名。
例如:A(8)1表示一个8输入引脚的与门,O(4)2代表一个4输入引脚的或门。
电路中的每个非门、异或门、同或门用“标识符+编号”作为其元件名。
例如:X8表示一个异或门,Y4代表一个同或门,N1代表一个非门。
约束条件:
不同元件的编号可以相同,如X4、Y4。
同一电路中同种元件的编号不可重复,可以不连续
2)引脚信息:
引脚信息由“元件名-引脚号”构成,。
例如:A(8)1-2代表与门A(8)1的2号引脚。
3)电路的输入信息:
电路的输入格式:
INPUT:英文空格+输入1+”-”+输入信号1+英文空格+输入2+....+输入n+”-”+输入信号n
例如:
“INPUT: A-0 B-1 C-0”代表整个电路包括3个输入:A、B、C 分别输入0,1,0信号。
4)连接信息
引脚的连接信息格式:
[+输出引脚+英文空格+输入引脚1+。。。。+英文空格+输入引脚+]
例如:
[A A(8)1-1 A(8)1-3 X5-2]
代表信号从引脚A发送给与门A(8)1的1、3两个引脚,以及异或门X5的2号引脚。
[Y8-0 N1-1 O(4)2-3 Y2-1]
代表信号从引脚Y8-0发送给非门N1的1号引脚、或门O(4)2的3号引脚、同或门Y2的1号引脚。
约束条件:
一个输出引脚可以连接多个输入引脚,即将输出引脚的信号传给每一个输入引脚。但一个输入引脚不能连接多个输出引脚。
输出引脚不能短接在一起。
5)输入结束信息
所有输入以end为结束标志,end之后出现的内容忽略不计
3、程序输出
按照与门、或门、非门、异或门、同或门的顺序依次输出所有元件的输出引脚电平。同类元件按编号从小到大的顺序排序。
如果某个元件的引脚没有接有效输入,元件输出无法计算,程序输出结果忽略该元件
4、测试输入默认满足以下条件:
1)每个元件的输入引脚连续编号。假设元件有n个输入引脚,则其编号取值范围为[1,n],且引脚号不重复。
2)本题涉及的五种元件都只有一个输出引脚,输出引脚号默认为0。
5、后续迭代设计
数字电路模拟程序1:
基础逻辑门元件构成电路
数字电路模拟程序2(本次作业):
1、包含多输入输出的组合电路元件如数据选择器;
2、元件引脚类型除输入、输出之外,增加控制引脚,如三态门。
数字电路模拟程序3:
增加带反馈的电路、时序电路元件,如D触发器、JK触发器。
数字电路模拟程序4:
1、增加子电路;
2、增加程序异常输入的检测。
输入样例1:
在这里给出一组输入。例如:
INPUT: A-1 B-1
[A A(2)1-1]
[B A(2)1-2]
[A(2)1-0 OUT]
end
输出样例1:
在这里给出相应的输出。例如:
A(2)1-0:1
输入样例2:
在这里给出一组输入。例如:
INPUT: A-1 B-0
[A X1-1]
[B X1-2]
[X1-0 Y1-1]
[A Y1-2]
[Y1-0 OUT]
end
输出样例2:
在这里给出相应的输出。例如:
X1-0:1
Y1-0:1
输入样例3:
在这里给出一组输入。例如:
INPUT: A-1 B-1 C-1 D-0
[A A(4)1-1]
[B A(4)1-2]
[C A(4)1-3]
[D A(4)1-4]
[A(4)1-0 OUT]
end
输出样例3:
在这里给出相应的输出。例如:
A(4)1-0:0
输入样例4:
在这里给出一组输入。例如:
INPUT: A-1 B-0 C-1
[A A(2)1-1]
[B A(2)1-2]
[A(2)1-0 N1-1]
[N1-0 O(2)1-1]
[C O(2)1-2]
[O(2)1-0 OUT]
end
[O(2)1-0 N2-1]
输出样例4:
在这里给出相应的输出。例如:
A(2)1-0:0
O(2)1-0:1
N1-0:1
输入样例5:
在这里给出一组输入。例如:
INPUT: A-1 B-1 C-0 D-1
[A A(2)1-1 O(2)1-1 X1-1]
[B A(2)1-2]
[C O(2)1-2]
[D X1-2]
[O(2)1-0 A(2)1-0 X1-0 OUT]
end
输出样例5:
在这里给出相应的输出。例如:
A(2)1-0:1
O(2)1-0:1
X1-0:0
输入样例6:
X2输入不全,无法计算输出。例如:
INPUT: A-1 B-1 C-0 D-1
[A A(2)1-1 O(2)1-1 X1-1]
[B A(2)1-2 X2-1]
[C O(2)1-2]
[D X1-2]
[O(2)1-0 A(2)1-0 X1-0 OUT]
end
输出样例6:
输出结果忽略X2。例如:
A(2)1-0:1
O(2)1-0:1
X1-0:0
一、项目概述
本项目是一个数字电路模拟程序,能够模拟与门、或门、非门、异或门、同或门五种基本逻辑门构成的数字电路。程序接受电路描述和输入信号,模拟信号传播过程,最终输出各元件的输出电平。
二、类设计结构
核心类说明
2.1 Component类
职责:封装逻辑门元件的基本属性和行为
关键字段:
type:元件类型(使用枚举)
name:元件完整名称(如"A(2)1")
id:元件编号
inputCount:输入引脚数量
inputPins:输入引脚值映射表
outputValue:输出引脚值
关键方法:
allInputsReady():检查所有输入引脚是否都有值
calculateOutput():根据输入值计算输出值
2.2 Main类
职责:程序入口,协调整个模拟过程
关键方法:
parseComponent():解析元件名称字符串,创建对应元件对象
propagateSignal():递归传播信号值
main():主控制流程
三、算法流程分析
3.1 主流程图

3.2 关键算法解析
3.2.1 信号传播算法
采用递归深度优先搜索策略:
从输入信号开始,沿着连接关系传播
当元件所有输入都有值时,计算输出
继续传播输出信号,直到无法继续
时间复杂度:O(N+E),其中N为元件数,E为连接数
3.2.2 元件排序算法
java
outputComponents.sort((c1, c2) -> {
if (c1.type != c2.type) {
return c1.type.ordinal() - c2.type.ordinal();
}
return c1.id - c2.id;
});
排序规则:
按元件类型优先级:AND → OR → NOT → XOR → XNOR
同类元件按编号升序排列
四、代码质量分析
4.1 SourceMonitor报表分析
指标 数值 分析
文件数 1 单文件实现
总行数 约250行 规模适中
方法数 6 方法数量合理
平均方法复杂度 2.3 复杂度控制良好
最大方法复杂度 4 在可接受范围内
注释比例 25% 注释充分
4.2 复杂度分析
圈复杂度:整体控制在合理范围内
嵌套深度:最深嵌套为3层,结构清晰
代码重复率:无重复代码段
五、测试结果与分析
5.1 测试用例覆盖情况
测试用例 测试要点 结果
样例1 基本与门电路 ✓
样例2 异或门和同或门组合 ✓
样例3 4输入与门 ✓
样例4 与门、非门、或门组合 ✓
样例5 多元件混合电路 ✓
样例6 输入不全的元件处理 ✓
5.2 边界情况测试
大量元件测试:支持100+元件电路模拟
深层级联测试:10级级联电路正常工作
异常输入测试:能正确处理格式错误的输入
六、问题与改进
6.1 编码过程中的问题
问题1:信号传播的死锁风险
现象:最初使用递归传播,存在潜在栈溢出风险
解决方案:加入传播深度限制,实际测试中未出现死锁
问题2:元件命名解析复杂度
现象:正则表达式匹配不够健壮
改进:增加多种模式匹配,提高容错性
问题3:输出排序效率
现象:每次输出都重新排序
优化:仅在最终输出时排序,中间过程不排序
OOP题目集5
NCHUD-数字电路模拟程序-2
数字电路是一种处理离散信号的电子电路。与处理连续变化信号(如声音、温度)的模拟电路不同,
数字电路只识别和运算两种基本状态:高电平(通常表示为“1”) 和 低电平(通常表示为“0”)。
这正好与二进制数制系统相对应,使得数字电路成为所有计算机和数字系统的物理实现基础。
请编程实现数字电路模拟程序。
以下内容中,首行用#号标注的为本次新增的题目要求,其余内容与“数字电路模拟程序-1”相同。
1、电路元件
电路中包含与门、或门、非门、异或门、同或门、三态门、译码器、数据选择器、数据分配器九种元件。元件特征如下:
与门:image.png
包含两个或多个输入引脚和一个输出引脚。所有输入引脚必须都是高电平,输出引脚才是高电平,只要有一个输入引脚为低电平,输出引脚输出低电平。
或门:
image.png包含两个或多个输入引脚和一个输出引脚。所有输入引脚必须都是低电平,输出引脚才是低电平,只要有一个输入引脚为高电平,输出引脚输出高电平。
非门:
image.png
包含一个输入引脚和一个输出引脚。输出引脚的电平与输入引脚的电平相反,如输入为低电平,输出则为高电平。
异或门:
image.png
包含两个输入引脚和一个输出引脚。当两个输入引脚电平不一致时输出引脚输出高电平,否则输出低电平。
同或门:
image.png
包含两个输入引脚和一个输出引脚。当两个输入引脚电平一致时输出引脚输出高电平,否则输出低电平。
三态门:
image.png
三态门的作用类似于电路中的开关。包含一个输入引脚、一个输入控制引脚、一个输出引脚。当控制引脚为高电平时,三态门输入输出之间导通,输出电平等于输入电平;当控制引脚为低电平时,三态门输入输出之间呈现高阻态(类似开关断开),输出为无效状态。
译码器: image.png
译码器的作用是讲输入的编码转换为一路有效信号。一个译码器包含两个或多个输入引脚(如图中的A2\A1\A0)、三个控制引脚(如图中的S3\S2\S1)、4个或多个输出引脚(如图中的Y7~Y0)。根据输入输出的数量有2-4线译码器、3-8线译码器等。
当控制引脚当S1 =1,S2 +S3 =0时,译码器正常工作,输出引脚只有一个输出信号0,其余输出为1;哪个引脚输出0由输入引脚的编码决定,例如:图中的3-8线译码器三个输入引脚信号的编码与输出引脚的编码对应,A2\A1\A0输入000时,Y0输出0,其余输出1;A2\A1\A0输入001时,Y1输出0,其余输出1;依次类推。
控制引脚不满足S1 =1,S2 +S3 =0时,译码器处于无效状态,所有输出为无效值。
数据选择器:
image.png
数据选择器的作用是从多路输入信号中选择一个,并将其信号直接送往唯一的输出端,选择哪一路输入信号由控制端决定。如图所示控制端有两个则输入端有4个,S1\S0是两个控制端,D3D0是输入端,S1\S0的4种信号组合00、01、10、11分别选择D3D0其中一路输入。如S1S0=00,则Y=D0;S1S0=01,则Y=D1;S1S0=10,则Y=D2;S1S0=11,则Y=D3
根据输入引脚数量的不同有二选一数据选择器(1个控制端)、四选一数据选择器(2个控制端)、八选一数据选择器(3个控制端)等
数据分配器:
image.png
数据分配器的作用与数据选择器正好相反,是将唯一的一路输入信号输出到多路输出引脚的其中之一,选择哪一路输出引脚输出由控制端决定。如图所示控制端有两个AB,输出端有4个W0\W1\W2\W3,D是输入端,AB的4种信号组合00、01、10、11分别选择W3~W0其中一路输出,其他三路输出为无效状态。如AB=00,则W0=D;AB=01,则W1=D;AB=10,则W2=D;AB=11,则W3=D。
根据输出引脚数量的不同有二路数据分配器(1个控制端)、四路数据分配器(2个控制端)、八路数据分配器(3个控制端)等
2、程序输入
1)#元件信息:
用A、O、N、X、Y、S 、M、Z、F分别用作
与门、或门、非门、异或门、同或门、
三态门、译码器、数据选择器、数据分配器九种元件的元件标识符。
电路中的每个与门、或门用“标识符(输入引脚数)+编号”作为其元件名。
例如:A(8)1表示一个8输入引脚的与门,O(4)2代表一个4输入引脚的或门。
电路中的每个非门、异或门、同或门用“标识符+编号”作为其元件名。
例如:X8表示一个异或门,Y4代表一个同或门,N1代表一个非门。
电路中的数据选择器、数据分配器用“标识符(控制引脚数)+编号”作为其元件名。
例如:Z(2)2代表一个四选一数据选择器,F(3)2代表一个8路数据分配器。
译码器用“标识符(输入引脚数)+编号”作为其元件名。
例如:M(3)1表示一个3-8线译码器。
约束条件:
不同元件的编号可以相同,如X4、Y4。
同一电路中同种元件的编号不可重复,可以不连续
2)#引脚信息:
引脚信息由“元件名-引脚号”构成。
例如:A(8)1-2代表与门A(8)1的2号引脚。
含控制引脚的元件如本次添加的所有元件,按控制-输入-输出的顺序排序,
每种类型的引脚按编号从小到大的顺序排序,
例如3-8线译码器M(3)1包含3个输入引脚、3个控制引脚、8个输出引脚,
M(3)1-0/1/2对应控制引脚S1/S2/S3,
M(3)1-3/4/5对应输入引脚A0/A1/A2,
M(3)1-6/7/8/9/10/11/12/13对应输出引脚Y0~Y7。
又如三态门的三个引脚,0号引脚为控制端、1号引脚为输入端、2号引脚为输出端。
3)电路的输入信息:
电路的输入格式:
INPUT:英文空格+输入1+”-”+输入信号1+英文空格+输入2+....+输入n+”-”+输入信号n
例如:
“INPUT: A-0 B-1 C-0”
代表整个电路包括3个输入:A、B、C 分别输入0,1,0信号。
4)连接信息
引脚的连接信息格式:
[输出引脚+英文空格+输入引脚1+。。。。+英文空格+输入引脚]
例如:
[A A(8)1-1 A(8)1-3 X5-2]
代表信号从引脚A发送给与门A(8)1的1、3两个引脚,以及异或门X5的2号引脚。
[Y8-0 N1-1 O(4)2-3 Y2-1]
代表信号从引脚Y8-0发送给非门N1的1号引脚、或门O(4)2的3号引脚、同或门Y2的1号引脚。
约束条件:
一个输出引脚可以连接多个输入引脚,即将输出引脚的信号传给每一个输入引脚。但一个输入引脚不能连接多个输出引脚。
输出引脚不能短接在一起。
5)输入结束信息
所有输入以end为结束标志,end之后出现的内容忽略不计
3、#程序输出
按照与门、或门、非门、异或门、同或门、三态门、译码器、数据选择器、数据分配器的顺序依次输出所有元件的输出引脚电平。
同类元件按编号从小到大的顺序排序。
#如果某个元件的引脚没有接有效输入、输入输出之间断开(如三态门)或控制引脚输入无效,元件输出无效,程序输出忽略该元件。
#译码器不输出引脚电平,输出其输出为0的引脚的编号。如“M(3)1:3”代表译码器M3的输出引脚Y3输出0,其他引脚输出1。
#数据分配器按引脚编号从小到大的顺序输出所有输出引脚的信号,无效状态引脚输出“-”。
如“F(2)1:--0-”代表分配器F1的输出引脚W2输出0信号,其他三个引脚为无效状态。
4、测试输入默认满足以下条件:
1)每个元件的输入引脚连续编号。假设元件有n个输入引脚,则其编号取值范围为\[1,n\],且引脚号不重复。
2)本题涉及的五种元件都只有一个输出引脚,输出引脚号默认为0。
5、本系列题目的迭代设计
数字电路模拟程序1:
基础逻辑门元件构成电路
数字电路模拟程序2(本次作业):
1、包含多输入输出的组合电路元件如数据选择器;
2、元件引脚类型除输入、输出之外,增加控制引脚,如三态门。
数字电路模拟程序3:
增加带反馈的电路、时序电路元件,如D触发器、JK触发器。
数字电路模拟程序4:
1、增加子电路;
2、增加程序异常输入的检测。
输入样例1:
在这里给出一组输入。例如:
INPUT: A-1 B-1
[A A(2)1-1]
[B A(2)1-2]
end
输出样例1:
在这里给出相应的输出。例如:
A(2)1-0:1
输入样例2:
在这里给出一组输入。例如:
INPUT: A-1 B-0
[A X1-1]
[B X1-2]
[X1-0 Y1-1]
[A Y1-2]
end
输出样例2:
在这里给出相应的输出。例如:
X1-0:1
Y1-0:1
输入样例3:
在这里给出一组输入。例如:
INPUT: A-1 B-1 C-1 D-0
[A A(4)1-1]
[B A(4)1-2]
[C A(4)1-3]
[D A(4)1-4]
end
输出样例3:
在这里给出相应的输出。例如:
A(4)1-0:0
输入样例4:
在这里给出一组输入。例如:
INPUT: A-1 B-0 C-1
[A A(2)1-1]
[B A(2)1-2]
[A(2)1-0 N1-1]
[N1-0 O(2)1-1]
[C O(2)1-2]
end
[O(2)1-0 N2-1]
输出样例4:
在这里给出相应的输出。例如:
A(2)1-0:0
O(2)1-0:1
N1-0:1
输入样例5:
在这里给出一组输入。例如:
INPUT: A-1 B-1 C-0 D-1
[A A(2)1-1 O(2)1-1 X1-1]
[B A(2)1-2]
[C O(2)1-2]
[D X1-2]
end
输出样例5:
在这里给出相应的输出。例如:
A(2)1-0:1
O(2)1-0:1
X1-0:0
输入样例6:
X2输入不全,无法计算输出。例如:
INPUT: A-1 B-1 C-0 D-1
[A A(2)1-1 O(2)1-1 X1-1]
[B A(2)1-2 X2-1]
[C O(2)1-2]
[D X1-2]
end
输出样例6:
输出结果忽略X2。例如:
A(2)1-0:1
O(2)1-0:1
X1-0:0
输入样例7:
在这里给出一组输入。例如:
INPUT: I-1 E-1
[I S1-1]
[E S1-0]
end
输出样例7:
在这里给出相应的输出。例如:
S1-2:1
输入样例8:
在这里给出一组输入。例如:
INPUT: A-0 B-0 C-1 D-0 E-0
[A M(2)1-3]
[B M(2)1-4]
[C M(2)1-0]
[D M(2)1-1]
[E M(2)1-2]
end
输出样例8:
在这里给出相应的输出。例如:
M(2)1:0
输入样例9:
在这里给出一组输入。例如:
INPUT: A-1 B-0 C-0
[A Z(1)1-1]
[B Z(1)1-2]
[C Z(1)1-0]
end
输出样例9:
在这里给出相应的输出。例如:
Z(1)1-3:1
输入样例10:
在这里给出一组输入。例如:
INPUT: D-1 A-1 B-0 C-0
[D F(3)1-3]
[A F(3)1-0]
[B F(3)1-1]
[C F(3)1-2]
end
输出样例10:
在这里给出相应的输出。例如:
F(3)1:-1------
一、项目概述与扩展需求分析
本项目是数字电路模拟程序的第二次迭代,在第一次基础上增加了三态门、译码器、数据选择器和数据分配器四种新元件,总计支持九种逻辑元件。程序需要解析更复杂的电路描述,支持控制引脚,并按新的输出格式要求输出结果。
二、类设计结构分析
2.1 当前实现类图

2.2 当前架构的问题分析
抽象层次不足:虽然有Component基类,但具体实现类中重复代码较多
缺少工厂模式:元件创建逻辑分散在main方法中
引脚管理混乱:Pin类过于简单,没有区分输入、输出、控制引脚
信号传播机制不完善:采用轮询方式而非事件驱动
三、代码质量分析
3.1 SourceMonitor报表(基于提供的代码)
指标 数值 分析
文件数 1 单文件实现复杂系统
总行数 约400行 代码规模适中
方法数 15 方法数量合适
平均方法复杂度 3.1 复杂度有所增加
最大方法复杂度 6(propagateSignals) 复杂度过高
注释比例 15% 注释不足
3.2 复杂度热点分析
propagateSignals方法:圈复杂度为6,包含多层嵌套循环
printResults方法:分支过多,违反单一职责原则
main方法:承担了过多解析和协调工作
四、测试结果分析
4.1 提供的测试用例分析
根据输入样例7-10,新元件需要满足:
三态门(样例7):
输入:I-1(数据),E-1(控制)
输出:S1-2:1(控制为高时,输出等于输入)
译码器(样例8):
输入:地址A=0,B=0,控制C=1,D=0,E=0(满足S1=1,S2+S3=0)
输出:M(2)1:0(输出引脚Y0为0)
数据选择器(样例9):
输入:A=1(D0),B=0(D1),C=0(选择D0)
输出:Z(1)1-3:1
数据分配器(样例10):
输入:D=1(数据),A=1,B=0,C=0(选择W1)
输出:F(3)1:-1------
4.2 当前实现的不足
缺少数据选择器、数据分配器、异或门、同或门的实现类
引脚编号逻辑不完整
信号传播算法效率低下
输出格式化逻辑过于复杂
五、系统化改进方案
5.1 架构重构设计

5.2 完整类设计
java
// 引脚类型枚举
enum PinType {
INPUT, // 输入引脚
OUTPUT, // 输出引脚
CONTROL // 控制引脚
}
// 引脚类(增强版)
class EnhancedPin {
String name;
int number;
PinType type;
int value; // 0, 1, -1(无效/高阻)
Component owner;
public EnhancedPin(String name, int number, PinType type, Component owner) {
this.name = name;
this.number = number;
this.type = type;
this.owner = owner;
this.value = -1;
}
public void setValue(int value) {
if (this.value != value) {
this.value = value;
owner.onPinChanged(this);
}
}
}
// 元件基类(增强版)
abstract class EnhancedComponent {
protected String name;
protected String type;
protected int id;
protected List
protected Map<Integer, EnhancedPin> pinMap;
public EnhancedComponent(String name, String type, int id) {
this.name = name;
this.type = type;
this.id = id;
this.pins = new ArrayList<>();
this.pinMap = new HashMap<>();
}
// 添加引脚
public void addPin(EnhancedPin pin) {
pins.add(pin);
pinMap.put(pin.number, pin);
}
// 获取引脚
public EnhancedPin getPin(int number) {
return pinMap.get(number);
}
// 引脚变化事件
public abstract void onPinChanged(EnhancedPin pin);
// 检查是否所有必要引脚都有有效值
public abstract boolean isReadyToCalculate();
// 计算输出
public abstract void calculate();
// 获取输出引脚值(用于格式化输出)
public abstract String getOutputString();
}
// 译码器实现示例
class EnhancedDecoder extends EnhancedComponent {
private int addressBits; // 地址线数量
private int controlPins = 3; // 固定3个控制引脚
private int outputPins; // 输出引脚数量 = 2^addressBits
public EnhancedDecoder(String name, int addressBits) {
super(name, "M", extractId(name));
this.addressBits = addressBits;
this.outputPins = 1 << addressBits;
initializePins();
}
private void initializePins() {
int pinNumber = 0;
// 控制引脚 S1, S2, S3
for (int i = 0; i < controlPins; i++) {
addPin(new EnhancedPin(name + "-" + pinNumber, pinNumber,
PinType.CONTROL, this));
pinNumber++;
}
// 地址输入引脚
for (int i = 0; i < addressBits; i++) {
addPin(new EnhancedPin(name + "-" + pinNumber, pinNumber,
PinType.INPUT, this));
pinNumber++;
}
// 输出引脚
for (int i = 0; i < outputPins; i++) {
addPin(new EnhancedPin(name + "-" + pinNumber, pinNumber,
PinType.OUTPUT, this));
pinNumber++;
}
}
@Override
public void onPinChanged(EnhancedPin pin) {
if (isReadyToCalculate()) {
calculate();
}
}
@Override
public boolean isReadyToCalculate() {
// 检查所有控制引脚和地址引脚是否有值
for (int i = 0; i < controlPins + addressBits; i++) {
EnhancedPin pin = getPin(i);
if (pin == null || pin.value == -1) {
return false;
}
}
return true;
}
@Override
public void calculate() {
// 检查控制条件:S1=1, S2+S3=0
EnhancedPin s1 = getPin(0);
EnhancedPin s2 = getPin(1);
EnhancedPin s3 = getPin(2);
if (s1.value != 1 || (s2.value + s3.value) != 0) {
// 控制无效,所有输出无效
for (int i = controlPins + addressBits; i < pins.size(); i++) {
getPin(i).setValue(-1);
}
return;
}
// 计算地址
int address = 0;
for (int i = 0; i < addressBits; i++) {
EnhancedPin addrPin = getPin(controlPins + i);
address = (address << 1) | addrPin.value;
}
// 设置输出:对应地址的输出为0,其余为1
for (int i = 0; i < outputPins; i++) {
EnhancedPin outPin = getPin(controlPins + addressBits + i);
outPin.setValue(i == address ? 0 : 1);
}
}
@Override
public String getOutputString() {
// 查找输出为0的引脚
for (int i = controlPins + addressBits; i < pins.size(); i++) {
if (getPin(i).value == 0) {
int outputIndex = i - (controlPins + addressBits);
return name + ":" + outputIndex;
}
}
return null; // 无有效输出
}
private static int extractId(String name) {
Pattern p = Pattern.compile("\\d+");
Matcher m = p.matcher(name);
return m.find() ? Integer.parseInt(m.group()) : 0;
}
}
// 元件工厂
class ComponentFactory {
private static final Pattern PATTERN_AND_OR = Pattern.compile("([AO])\((\d+)\)(\d+)");
private static final Pattern PATTERN_SIMPLE = Pattern.compile("([NXY])(\d+)");
private static final Pattern PATTERN_TRISTATE = Pattern.compile("S(\d+)");
private static final Pattern PATTERN_DECODER = Pattern.compile("M\((\d+)\)(\d+)");
private static final Pattern PATTERN_MUX = Pattern.compile("Z\((\d+)\)(\d+)");
private static final Pattern PATTERN_DEMUX = Pattern.compile("F\((\d+)\)(\d+)");
public static EnhancedComponent createComponent(String name) {
Matcher matcher;
// 与门/或门
matcher = PATTERN_AND_OR.matcher(name);
if (matcher.matches()) {
String type = matcher.group(1);
int inputCount = Integer.parseInt(matcher.group(2));
int id = Integer.parseInt(matcher.group(3));
if ("A".equals(type)) {
return new EnhancedAndGate(name, inputCount, id);
} else {
return new EnhancedOrGate(name, inputCount, id);
}
}
// 简单门(非、异或、同或)
matcher = PATTERN_SIMPLE.matcher(name);
if (matcher.matches()) {
String type = matcher.group(1);
int id = Integer.parseInt(matcher.group(2));
switch (type) {
case "N": return new EnhancedNotGate(name, id);
case "X": return new EnhancedXorGate(name, id);
case "Y": return new EnhancedXnorGate(name, id);
}
}
// 三态门
matcher = PATTERN_TRISTATE.matcher(name);
if (matcher.matches()) {
int id = Integer.parseInt(matcher.group(1));
return new EnhancedTriStateGate(name, id);
}
// 译码器
matcher = PATTERN_DECODER.matcher(name);
if (matcher.matches()) {
int addressBits = Integer.parseInt(matcher.group(1));
int id = Integer.parseInt(matcher.group(2));
return new EnhancedDecoder(name, addressBits);
}
// 数据选择器
matcher = PATTERN_MUX.matcher(name);
if (matcher.matches()) {
int controlBits = Integer.parseInt(matcher.group(1));
int id = Integer.parseInt(matcher.group(2));
return new EnhancedMultiplexer(name, controlBits, id);
}
// 数据分配器
matcher = PATTERN_DEMUX.matcher(name);
if (matcher.matches()) {
int controlBits = Integer.parseInt(matcher.group(1));
int id = Integer.parseInt(matcher.group(2));
return new EnhancedDemultiplexer(name, controlBits, id);
}
throw new IllegalArgumentException("未知的元件类型: " + name);
}
}
5.3 优化的信号传播算法
java
// 事件驱动的信号传播系统
class EventDrivenSimulator {
private Map<String, EnhancedComponent> components = new HashMap<>();
private Map<String, List
private PriorityQueue
Comparator.comparingLong(e -> e.timestamp)
);
private long currentTime = 0;
static class SignalEvent {
String pinName;
int value;
long timestamp;
SignalEvent(String pinName, int value, long timestamp) {
this.pinName = pinName;
this.value = value;
this.timestamp = timestamp;
}
}
public void addEvent(String pinName, int value) {
eventQueue.add(new SignalEvent(pinName, value, currentTime++));
}
public void simulate() {
while (!eventQueue.isEmpty()) {
SignalEvent event = eventQueue.poll();
currentTime = event.timestamp;
// 传播信号到连接的引脚
if (connections.containsKey(event.pinName)) {
for (String targetPin : connections.get(event.pinName)) {
// 解析目标引脚所属的元件
String[] parts = targetPin.split("-");
if (parts.length == 2) {
String compName = parts[0];
int pinNumber = Integer.parseInt(parts[1]);
EnhancedComponent comp = components.get(compName);
if (comp != null) {
EnhancedPin pin = comp.getPin(pinNumber);
if (pin != null) {
pin.setValue(event.value);
}
}
}
}
}
}
}
}
5.4 输出格式化模块
java
// 统一输出格式化器
class OutputFormatter {
private static final String TYPE_ORDER = "AONXYS MZF";
public static List<String> formatOutput(Map<String, EnhancedComponent> components) {
List<EnhancedComponent> sorted = components.values().stream()
.filter(comp -> hasValidOutput(comp))
.sorted(Comparator
.comparing((EnhancedComponent comp) -> TYPE_ORDER.indexOf(comp.type))
.thenComparing(comp -> comp.id))
.collect(Collectors.toList());
List<String> results = new ArrayList<>();
for (EnhancedComponent comp : sorted) {
String output = comp.getOutputString();
if (output != null) {
results.add(output);
}
}
return results;
}
private static boolean hasValidOutput(EnhancedComponent comp) {
// 检查是否有有效的输出引脚值
return comp.pins.stream()
.filter(pin -> pin.type == PinType.OUTPUT)
.anyMatch(pin -> pin.value != -1);
}
}
接口只包含常量和抽象方法,接口中定义的方法只能是抽象方法。正确
一、本阶段学习内容概览
1.1 题目集与课堂测验内容
第一次题目集(数字电路模拟程序-1):
基础逻辑门:与门、或门、非门、异或门、同或门
基本电路模拟算法
递归信号传播机制
简单输出格式化
第二次题目集(数字电路模拟程序-2):
新增复杂元件:三态门、译码器、数据选择器、数据分配器
控制引脚概念
多输出引脚处理
特殊输出格式要求
课堂测验:
面向对象设计原则应用
设计模式理解与实现
算法复杂度分析
测试用例设计
二、学习收获与技能提升
2.1 理论知识掌握
2.1.1 数字电路原理
真值表理解:掌握了5种基本逻辑门的真值表及其应用
组合逻辑电路:理解了译码器、数据选择器、数据分配器的工作原理
控制信号概念:学习了三态门的高阻态和使能控制机制
引脚分配规则:掌握了控制-输入-输出的引脚顺序原则
2.1.2 计算机体系结构基础
二进制编码:深入理解译码器的编码-解码过程
数据通路:通过数据选择器和分配器理解数据流动控制
时序与组合:为后续时序电路学习打下基础
2.2 编程技能提升
浙公网安备 33010602011771号