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 主流程图
image
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 当前实现类图
image
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 架构重构设计
image
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 pins;
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> connections = new HashMap<>();
private PriorityQueue eventQueue = new 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 编程技能提升

posted @ 2025-12-14 19:25  张亦驰1  阅读(3)  评论(0)    收藏  举报