PTA作业集4-6的总结
1. 前言
后3次主要应用是类与类之间的关系:关联,依赖,组合,聚合以及继承,多态等来完成数字电路的一系列题目,逐步迭代,相比与1-3的PTA题目集,这一次的题目集更加困难一点。
第一次作业
1.目标:基础逻辑门元件构成电路。
1、电路元件
电路中包含与门、或门、非门、异或门、同或门五种元件。元件特征如下:
与门:
包含两个或多个输入引脚和一个输出引脚。所有输入引脚必须都是高电平,输出引脚才是高电平,只要有一个输入引脚为低电平,输出引脚输出低电平。
或门:
包含两个或多个输入引脚和一个输出引脚。所有输入引脚必须都是低电平,输出引脚才是低电平,只要有一个输入引脚为高电平,输出引脚输出高电平。
非门:
包含一个输入引脚和一个输出引脚。输出引脚的电平与输入引脚的电平相反,如输入为低电平,输出则为高电平。
异或门:
包含两个输入引脚和一个输出引脚。当两个输入引脚电平不一致时输出引脚输出高电平,否则输出低电平。
同或门:
包含两个输入引脚和一个输出引脚。当两个输入引脚电平一致时输出引脚输出高电平,否则输出低电平。
2.代码如下:
import java.util.Scanner;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Main{
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
Circuit circuit=new Circuit();
while(sc.hasNextLine()){
String line=sc.nextLine();
boolean f=false;
if(line.length()==3){
if(line.charAt(0)=='e'&&line.charAt(1)=='n'&&line.charAt(2)=='d')
f=true;
}
if(f)break;
boolean e=true;
for(int i=0;i<line.length();i++){
if(line.charAt(i)!=' '){
e=false;
break;
}
}
if(e)continue;
boolean t=false;
if(line.length()>=6){
if(line.charAt(0)=='I'&&line.charAt(1)=='N'&&line.charAt(2)=='P'&&line.charAt(3)=='U'&&line.charAt(4)=='T'&&line.charAt(5)==':')
t=true;
}
if(t)circuit.readInputLine(line);
else if(line.charAt(0)=='[')circuit.readConnectLine(line);
}
circuit.computeAllGate();
circuit.sortGate();
circuit.printResult();
}
}
class Gate implements Comparable<Gate>{
private String name;
private char type;
private int inputNum;
private int id;
private Integer output;
public Gate(String name,char type,int inputNum,int id){
this.name=name;
this.type=type;
this.inputNum=inputNum;
this.id=id;
this.output=null;
}
public int compareTo(Gate other){
return this.id-other.id;
}
public String getName(){
return name;
}
public char getType(){
return type;
}
public int getInputNum(){
return inputNum;
}
public Integer getOutput(){
return output;
}
public void setOutput(Integer output){
this.output=output;
}
}
class Circuit{
private List<String> pinNames;
private List<Integer> pinValues;
private List<String> sourceList;
private List<List<String>> targetList;
private List<Gate> allGate;
private List<Gate> andGate;
private List<Gate> orGate;
private List<Gate> notGate;
private List<Gate> xorGate;
private List<Gate> xnorGate;
public Circuit(){
pinNames=new ArrayList<>();
pinValues=new ArrayList<>();
sourceList=new ArrayList<>();
targetList=new ArrayList<>();
allGate=new ArrayList<>();
andGate=new ArrayList<>();
orGate=new ArrayList<>();
notGate=new ArrayList<>();
xorGate=new ArrayList<>();
xnorGate=new ArrayList<>();
}
public void savePin(String name,int val){
pinNames.add(name);
pinValues.add(val);
}
public Integer searchPin(String pin){
for(int i=0;i<pinNames.size();i++){
if(pinNames.get(i).equals(pin)){
return pinValues.get(i);
}
}
return null;
}
public String findDriveSource(String targetPin){
for(int i=0;i<sourceList.size();i++){
List<String> targets=targetList.get(i);
for(String p:targets){
if(p.equals(targetPin)){
return sourceList.get(i);
}
}
}
return null;
}
public Gate searchGate(String gateName){
for(Gate g:allGate){
if(g.getName().equals(gateName)){
return g;
}
}
return null;
}
public void readInputLine(String line){
int idx=6;
while(idx<line.length()&&line.charAt(idx)==' ')idx++;
String cur="";
List<String> s=new ArrayList<>();
while(idx<line.length()){
char c=line.charAt(idx);
if(c==' '){
boolean b=!cur.equals("");
if(b){
s.add(cur);
cur="";
}
}else{
cur+=c;
}
idx++;
}
boolean b=!cur.equals("");
if(b)s.add(cur);
for(String item:s){
int m=0;
while(m<item.length()&&item.charAt(m)!='-')m++;
String nm="";
for(int k=0;k<m;k++)nm+=item.charAt(k);
int num=item.charAt(m+1)-'0';
savePin(nm,num);
}
}
public void readConnectLine(String line){
String cur="";
List<String> s=new ArrayList<>();
for(int i=1;i<line.length()-1;i++){
char c=line.charAt(i);
if(c==' '){
boolean b=!cur.equals("");
if(b){
s.add(cur);
cur="";
}
}else cur+=c;
}
boolean b=!cur.equals("");
if(b)s.add(cur);
String src=s.get(0);
List<String> tar=new ArrayList<>();
for(int i=1;i<s.size();i++)tar.add(s.get(i));
sourceList.add(src);
targetList.add(tar);
for(String t:tar){
boolean h=false;
for(int i=0;i<t.length();i++){
if(t.charAt(i)=='-'){
h=true;
break;
}
}
if(h){
createGate(t);
}
}
}
public void createGate(String pinStr){
int p=-1;
for(int i=0;i<pinStr.length();i++){
if(pinStr.charAt(i)=='-'){
p=i;
break;
}
}
if(p==-1)return;
String nm="";
for(int i=0;i<p;i++)nm+=pinStr.charAt(i);
if(searchGate(nm)!=null)return;
char t=nm.charAt(0);
Gate gate=null;
if(t=='A'||t=='O'){
int l=-1;
for(int i=0;i<nm.length();i++){
if(nm.charAt(i)=='('){
l=i;
break;
}
}
int r=-1;
for(int i=0;i<nm.length();i++){
if(nm.charAt(i)==')'){
r=i;
break;
}
}
if(l==-1||r==-1)return;
String s="";
for(int i=l+1;i<r;i++)s+=nm.charAt(i);
int ic=Integer.parseInt(s);
s="";
for(int i=r+1;i<nm.length();i++)s+=nm.charAt(i);
int gid=Integer.parseInt(s);
gate=new Gate(nm,t,ic,gid);
}else{
String s="";
for(int i=1;i<nm.length();i++)s+=nm.charAt(i);
int gid=Integer.parseInt(s);
int ic=1;
if(t=='X'||t=='Y')ic=2;
gate=new Gate(nm,t,ic,gid);
}
allGate.add(gate);
if(gate.getType()=='A')andGate.add(gate);
else if(gate.getType()=='O')orGate.add(gate);
else if(gate.getType()=='N')notGate.add(gate);
else if(gate.getType()=='X')xorGate.add(gate);
else if(gate.getType()=='Y')xnorGate.add(gate);
}
public Integer getPinValue(String pin){
Integer val=searchPin(pin);
if(val!=null)return val;
String src=findDriveSource(pin);
if(src==null)return null;
int p=-1;
for(int i=0;i<src.length();i++){
if(src.charAt(i)=='-'){
p=i;
break;
}
}
if(p==-1)return searchPin(src);
String nm="";
for(int i=0;i<p;i++)nm+=src.charAt(i);
Gate gate=searchGate(nm);
if(gate==null)return null;
calculateGate(gate);
return searchPin(src);
}
public void calculateGate(Gate gate){
if(gate.getOutput()!=null)return;
List<Integer> in=new ArrayList<>();
int num=gate.getInputNum();
for(int i=1;i<=num;i++){
String p=gate.getName()+"-"+i;
Integer v=getPinValue(p);
if(v==null)return;
in.add(v);
}
int res=0;
char t=gate.getType();
if(t=='A'){
res=1;
for(int v:in)if(v==0)res=0;
}else if(t=='O'){
res=0;
for(int v:in)if(v==1)res=1;
}else if(t=='N'){
res=1-in.get(0);
}else if(t=='X'){
res=in.get(0)^in.get(1);
}else if(t=='Y'){
res=in.get(0).equals(in.get(1))?1:0;
}
gate.setOutput(res);
savePin(gate.getName()+"-0",res);
}
public void computeAllGate(){
for(Gate g:allGate)calculateGate(g);
}
public void sortGate(){
Collections.sort(andGate);
Collections.sort(orGate);
Collections.sort(notGate);
Collections.sort(xorGate);
Collections.sort(xnorGate);
}
public void printResult(){
for(Gate g:andGate)if(g.getOutput()!=null)System.out.println(g.getName()+"-0:"+g.getOutput());
for(Gate g:orGate)if(g.getOutput()!=null)System.out.println(g.getName()+"-0:"+g.getOutput());
for(Gate g:notGate)if(g.getOutput()!=null)System.out.println(g.getName()+"-0:"+g.getOutput());
for(Gate g:xorGate)if(g.getOutput()!=null)System.out.println(g.getName()+"-0:"+g.getOutput());
for(Gate g:xnorGate)if(g.getOutput()!=null)System.out.println(g.getName()+"-0:"+g.getOutput());
}
}


代码的实现比较难,花了不是时间完成。
踩坑心得:没有踩坑,但是还是有一些代码上的语法错误,问题不是回答,自己解决了这些问题。
心得:通过这个OPP4让我使用了java代码来实现了一个复杂的问题并熟悉的解答了它。
第二次作业
1. 目标:在第一次的基础上完成:
(1).包含多输入输出的组合电路元件如数据选择器。
(2).元件引脚类型除输入、输出之外,增加控制引脚,如三态门。
2. 迭代:更为复制的电路。
3. 代码如下:
import java.util.Scanner;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Main{
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
Circuit circuit=new Circuit();
while(sc.hasNextLine()){
String line=sc.nextLine();
boolean f=false;
if(line.trim().equals("end")){
f=true;
}
if(f)break;
boolean e=true;
for(int i=0;i<line.length();i++){
if(line.charAt(i)!=' '){
e=false;
break;
}
}
if(e)continue;
boolean t=false;
if(line.startsWith("INPUT:"))
t=true;
if(t)circuit.readInputLine(line);
else if(line.charAt(0)=='[')circuit.readConnectLine(line);
}
circuit.computeAllGate();
circuit.sortGate();
circuit.printResult();
}
}
class Gate implements Comparable<Gate>{
private String name;
private char type;
private int inputNum;
private int ctrlNum;
private int outNum;
private int id;
private Integer output;
public Gate(String name,char type,int inputNum,int id){
this(name, type, inputNum, 0, 1, id);
}
public Gate(String name,char type,int inputNum,int ctrlNum,int outNum,int id){
this.name=name;
this.type=type;
this.inputNum=inputNum;
this.ctrlNum=ctrlNum;
this.outNum=outNum;
this.id=id;
this.output=null;
}
public int compareTo(Gate other){
return this.id-other.id;
}
public String getName(){
return name;
}
public char getType(){
return type;
}
public int getInputNum(){
return inputNum;
}
public int getCtrlNum(){return ctrlNum;}
public int getOutNum(){return outNum;}
public Integer getOutput(){
return output;
}
public void setOutput(Integer output){
this.output=output;
}
}
class Circuit{
private List<String> pinNames;
private List<Integer> pinValues;
private List<String> sourceList;
private List<List<String>> targetList;
private List<Gate> allGate;
private List<Gate> andGate;
private List<Gate> orGate;
private List<Gate> notGate;
private List<Gate> xorGate;
private List<Gate> xnorGate;
private List<Gate> triGate;
private List<Gate> decoderGate;
private List<Gate> muxGate;
private List<Gate> demuxGate;
private java.util.Map<String,Integer> decOutMap;
private java.util.Map<String,char[]> demuxOutMap;
public Circuit(){
pinNames=new ArrayList<>();
pinValues=new ArrayList<>();
sourceList=new ArrayList<>();
targetList=new ArrayList<>();
allGate=new ArrayList<>();
andGate=new ArrayList<>();
orGate=new ArrayList<>();
notGate=new ArrayList<>();
xorGate=new ArrayList<>();
xnorGate=new ArrayList<>();
triGate=new ArrayList<>();
decoderGate=new ArrayList<>();
muxGate=new ArrayList<>();
demuxGate=new ArrayList<>();
decOutMap=new java.util.HashMap<>();
demuxOutMap=new java.util.HashMap<>();
}
public void savePin(String name,int val){
pinNames.add(name);
pinValues.add(val);
}
public void savePinNull(String name){
pinNames.add(name);
pinValues.add(null);
}
public Integer searchPin(String pin){
for(int i=0;i<pinNames.size();i++){
if(pinNames.get(i).equals(pin)){
return pinValues.get(i);
}
}
return null;
}
public String findDriveSource(String targetPin){
for(int i=0;i<sourceList.size();i++){
List<String> targets=targetList.get(i);
for(String p:targets){
if(p.equals(targetPin)){
return sourceList.get(i);
}
}
}
return null;
}
public Gate searchGate(String gateName){
for(Gate g:allGate){
if(g.getName().equals(gateName)){
return g;
}
}
return null;
}
public void readInputLine(String line){
int idx=6;
while(idx<line.length()&&line.charAt(idx)==' ')idx++;
String cur="";
List<String> s=new ArrayList<>();
while(idx<line.length()){
char c=line.charAt(idx);
if(c==' '){
boolean b=!cur.equals("");
if(b){
s.add(cur);
cur="";
}
}else{
cur+=c;
}
idx++;
}
boolean b=!cur.equals("");
if(b)s.add(cur);
for(String item:s){
int m=0;
while(m<item.length()&&item.charAt(m)!='-')m++;
String nm="";
for(int k=0;k<m;k++)nm+=item.charAt(k);
int num=item.charAt(m+1)-'0';
savePin(nm,num);
}
}
public void readConnectLine(String line){
String cur="";
List<String> s=new ArrayList<>();
for(int i=1;i<line.length()-1;i++){
char c=line.charAt(i);
if(c==' '){
boolean b=!cur.equals("");
if(b){
s.add(cur);
cur="";
}
}else cur+=c;
}
boolean b=!cur.equals("");
if(b)s.add(cur);
String src=s.get(0);
List<String> tar=new ArrayList<>();
for(int i=1;i<s.size();i++)tar.add(s.get(i));
sourceList.add(src);
targetList.add(tar);
for(String t:tar){
boolean h=false;
for(int i=0;i<t.length();i++){
if(t.charAt(i)=='-'){
h=true;
break;
}
}
if(h){
createGate(t);
}
}
}
public void createGate(String pinStr){
int p=-1;
for(int i=0;i<pinStr.length();i++){
if(pinStr.charAt(i)=='-'){
p=i;
break;
}
}
if(p==-1)return;
String nm="";
for(int i=0;i<p;i++)nm+=pinStr.charAt(i);
if(searchGate(nm)!=null)return;
char t=nm.charAt(0);
Gate gate=null;
if(t=='A'||t=='O'){
int l=-1;
for(int i=0;i<nm.length();i++){
if(nm.charAt(i)=='('){
l=i;
break;
}
}
int r=-1;
for(int i=0;i<nm.length();i++){
if(nm.charAt(i)==')'){
r=i;
break;
}
}
if(l==-1||r==-1)return;
String s="";
for(int i=l+1;i<r;i++)s+=nm.charAt(i);
int ic=Integer.parseInt(s);
s="";
for(int i=r+1;i<nm.length();i++)s+=nm.charAt(i);
int gid=Integer.parseInt(s);
gate=new Gate(nm,t,ic,gid);
}
else if(t=='N'||t=='X'||t=='Y'){
String s="";
for(int i=1;i<nm.length();i++)s+=nm.charAt(i);
int gid=Integer.parseInt(s);
int ic=1;
if(t=='X'||t=='Y')ic=2;
gate=new Gate(nm,t,ic,gid);
}
else if(t=='S'){
String numStr=nm.substring(1);
int gid=Integer.parseInt(numStr);
gate=new Gate(nm, 'S',1,1,1,gid);
}
else if(t=='M'){
int lp=nm.indexOf('(');
int rp=nm.indexOf(')');
int inCnt=Integer.parseInt(nm.substring(lp+1,rp));
int gid=Integer.parseInt(nm.substring(rp+1));
int outCnt = 1 << inCnt;
gate=new Gate(nm,'M',inCnt,3,outCnt,gid);
}
else if(t=='Z'){
int lp=nm.indexOf('(');
int rp=nm.indexOf(')');
int ctrlCnt=Integer.parseInt(nm.substring(lp+1,rp));
int dataInCnt=1<<ctrlCnt;
int gid=Integer.parseInt(nm.substring(rp+1));
gate=new Gate(nm,'Z',dataInCnt,ctrlCnt,1,gid);
}
else if(t=='F'){
int lp=nm.indexOf('(');
int rp=nm.indexOf(')');
int ctrlCnt=Integer.parseInt(nm.substring(lp+1,rp));
int outCnt=1<<ctrlCnt;
int gid=Integer.parseInt(nm.substring(rp+1));
gate=new Gate(nm,'F',1,ctrlCnt,outCnt,gid);
}
if(gate==null) return;
allGate.add(gate);
if(gate.getType()=='A')andGate.add(gate);
else if(gate.getType()=='O')orGate.add(gate);
else if(gate.getType()=='N')notGate.add(gate);
else if(gate.getType()=='X')xorGate.add(gate);
else if(gate.getType()=='Y')xnorGate.add(gate);
else if(gate.getType()=='S')triGate.add(gate);
else if(gate.getType()=='M')decoderGate.add(gate);
else if(gate.getType()=='Z')muxGate.add(gate);
else if(gate.getType()=='F')demuxGate.add(gate);
}
public Integer getPinValue(String pin){
Integer val=searchPin(pin);
if(val!=null)return val;
String src=findDriveSource(pin);
if(src==null)return null;
int p=-1;
for(int i=0;i<src.length();i++){
if(src.charAt(i)=='-'){
p=i;
break;
}
}
if(p==-1)return searchPin(src);
String nm="";
for(int i=0;i<p;i++)nm+=src.charAt(i);
Gate gate=searchGate(nm);
if(gate==null)return null;
calculateGate(gate);
return searchPin(src);
}
public void calculateGate(Gate gate){
if(gate.getOutput()!=null)return;
String gName=gate.getName();
char t=gate.getType();
if(t=='A'||t=='O'||t=='N'||t=='X'||t=='Y'){
List<Integer> in=new ArrayList<>();
int num=gate.getInputNum();
for(int i=1;i<=num;i++){
String p=gName+"-"+i;
Integer v=getPinValue(p);
if(v==null)return;
in.add(v);
}
int res=0;
if(t=='A'){
res=1;
for(int v:in)if(v==0)res=0;
}else if(t=='O'){
res=0;
for(int v:in)if(v==1)res=1;
}else if(t=='N'){
res=1-in.get(0);
}else if(t=='X'){
res=in.get(0)^in.get(1);
}else if(t=='Y'){
res=in.get(0).equals(in.get(1))?1:0;
}
gate.setOutput(res);
savePin(gName+"-0",res);
return;
}
else if(t=='S'){
Integer ctrl=getPinValue(gName+"-0");
Integer dat=getPinValue(gName+"-1");
if(ctrl==null||dat==null) return;
if(ctrl==1){
gate.setOutput(dat);
savePin(gName+"-2", dat);
}else{
savePinNull(gName+"-2");
}
return;
}
else if(t=='M'){
int inCnt=gate.getInputNum();
Integer s1=getPinValue(gName+"-0");
Integer s2=getPinValue(gName+"-1");
Integer s3=getPinValue(gName+"-2");
if(s1==null||s2==null||s3==null) {
decOutMap.put(gName,null);
return;
}
boolean work=(s1==1)&&(s2+s3==0);
if(!work){
decOutMap.put(gName,null);
return;
}
int code=0;
for(int i=inCnt-1;i>=0;i--){
Integer bit=getPinValue(gName+"-"+(3+i));
if(bit==null) {
decOutMap.put(gName,null);
return;
}
code=(code<<1)|bit;
}
decOutMap.put(gName,code);
return;
}
else if(t=='Z'){
int k=gate.getCtrlNum();
int dataStart=k;
int outPinIdx=dataStart + gate.getInputNum();
int sel=0;
for(int i=k-1;i>=0;i--){
Integer b=getPinValue(gName+"-"+i);
if(b==null) return;
sel=(sel<<1)|b;
}
Integer selData=getPinValue(gName+"-"+(dataStart+sel));
if(selData==null) return;
gate.setOutput(selData);
savePin(gName+"-"+outPinIdx, selData);
return;
}
else if(t=='F'){
int k=gate.getCtrlNum();
int dPin=k;
int outTotal=gate.getOutNum();
int sel=0;
for(int i=k-1;i>=0;i--){
Integer b=getPinValue(gName+"-"+i);
if(b==null) return;
sel=(sel<<1)|b;
}
Integer dVal=getPinValue(gName+"-"+dPin);
if(dVal==null) return;
char[] res=new char[outTotal];
java.util.Arrays.fill(res,'-');
res[sel]=(dVal==1)?'1':'0';
demuxOutMap.put(gName, res);
return;
}
}
public void computeAllGate(){
for(Gate g:allGate)calculateGate(g);
}
public void sortGate(){
Collections.sort(andGate);
Collections.sort(orGate);
Collections.sort(notGate);
Collections.sort(xorGate);
Collections.sort(xnorGate);
Collections.sort(triGate);
Collections.sort(decoderGate);
Collections.sort(muxGate);
Collections.sort(demuxGate);
}
public void printResult(){
for(Gate g:andGate)if(g.getOutput()!=null)System.out.println(g.getName()+"-0:"+g.getOutput());
for(Gate g:orGate)if(g.getOutput()!=null)System.out.println(g.getName()+"-0:"+g.getOutput());
for(Gate g:notGate)if(g.getOutput()!=null)System.out.println(g.getName()+"-0:"+g.getOutput());
for(Gate g:xorGate)if(g.getOutput()!=null)System.out.println(g.getName()+"-0:"+g.getOutput());
for(Gate g:xnorGate)if(g.getOutput()!=null)System.out.println(g.getName()+"-0:"+g.getOutput());
for(Gate g:triGate){
Integer v=searchPin(g.getName()+"-2");
if(v!=null){
System.out.println(g.getName()+"-2:"+v);
}
}
for(Gate g:decoderGate){
Integer zeroIdx=decOutMap.get(g.getName());
if(zeroIdx!=null){
System.out.println(g.getName()+":"+zeroIdx);
}
}
for(Gate g:muxGate){
Integer v = g.getOutput();
if(v!=null){
int outNo=g.getCtrlNum()+g.getInputNum();
System.out.println(g.getName()+"-"+outNo+":"+v);
}
}
for(Gate g:demuxGate){
char[] arr=demuxOutMap.get(g.getName());
if(arr!=null){
System.out.println(g.getName()+":"+new String(arr));
}
}
}
}


相比与上一次代码这次代码的实现更为困难
踩坑心得:在完成代码后提交后没有满分,然后自己直接考虑是不是自己的代码在一些方面的处理存在bug,但是经过了很长时间的努力修改,还是没有得到满分。
心得: 虽然代码的每一个测试用例都过了,但是还是没有得到满分,建议可以给一点提示。
第三次作业.
1. 目标: 采用组合模式,将子电路和电路元件作为抽象的元件类的子类,即可以将子电路看作一种组合型的电路元件。组合模式通用类图如下:

图中可将Leaf作为元件类,Composite作为子电路类。
2. 代码如下:
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
Circuit circuit=new Circuit();
List<String> buffer = new ArrayList<>();
while(sc.hasNextLine()){
String line=sc.nextLine().trim();
if(line.isEmpty()) continue;
buffer.add(line);
if(line.equals("end")) break;
}
sc.close();
int ptr = 0;
while(ptr < buffer.size() && circuit.errorMsg == null) {
String cur = buffer.get(ptr);
if(cur.startsWith("C") && cur.endsWith(":")) {
ptr = circuit.parseSubCircuit(buffer, ptr);
} else break;
}
while(ptr < buffer.size() && circuit.errorMsg == null) {
String cur = buffer.get(ptr);
ptr++;
if(cur.startsWith("INPUT:"))
circuit.readInputLine(cur);
else if(cur.startsWith("[") && cur.endsWith("]"))
circuit.readConnectLine(cur);
}
if(circuit.errorMsg != null) {
System.out.println(circuit.errorMsg);
return;
}
circuit.printAllResult();
}
}
abstract class CircuitComponent {
protected String fullId;
public abstract Integer eval(Map<String, Integer> sigPool, Map<Integer, SubCircuit> subMap);
public void addChild(CircuitComponent c) { throw new UnsupportedOperationException(); }
public void removeChild(CircuitComponent c) { throw new UnsupportedOperationException(); }
public CircuitComponent getChild(int idx) { throw new UnsupportedOperationException(); }
public String getFullId() { return fullId; }
}
class Gate extends CircuitComponent implements Comparable<Gate>{
private String name;
private char type;
private int inputNum;
private int ctrlNum;
private int outNum;
private int id;
private Integer output;
public Gate(String name,char type,int inputNum,int id){
this(name, type, inputNum, 0, 1, id);
}
public Gate(String name,char type,int inputNum,int ctrlNum,int outNum,int id){
this.name=name;
this.type=type;
this.inputNum=inputNum;
this.ctrlNum=ctrlNum;
this.outNum=outNum;
this.id=id;
this.output=null;
}
@Override
public Integer eval(Map<String, Integer> sigPool, Map<Integer, SubCircuit> subMap){
return null;
}
public int compareTo(Gate other){
return this.id-other.id;
}
public String getName(){
return name;
}
public char getType(){
return type;
}
public int getInputNum(){
return inputNum;
}
public int getCtrlNum(){return ctrlNum;}
public int getOutNum(){return outNum;}
public Integer getOutput(){
return output;
}
public void setOutput(Integer output){
this.output=output;
}
}
class SubCircuit extends CircuitComponent {
public int cid;
public List<String> subInputs = new ArrayList<>();
public List<String> subOutputs = new ArrayList<>();
public List<CircuitComponent> children = new ArrayList<>();
public List<Gate> innerGates = new ArrayList<>();
public Map<String, List<String>> innerWires = new HashMap<>();
public Map<String, Integer> localSignal = new HashMap<>();
public boolean evaluated = false;
public SubCircuit(int id) {
this.cid = id;
this.fullId = "C" + id;
evaluated = false;
}
@Override
public void addChild(CircuitComponent c) {
children.add(c);
if(c instanceof Gate){
Gate g = (Gate)c;
if(!innerGates.contains(g)) innerGates.add(g);
}
}
@Override
public Integer eval(Map<String, Integer> outerSig, Map<Integer, SubCircuit> subMap) {
if(evaluated) return null;
localSignal.clear();
for(String in : subInputs) {
String outerKey = "C" + cid + "-" + in;
if(outerSig.containsKey(outerKey)) {
localSignal.put(in, outerSig.get(outerKey));
}
}
for(var entry : innerWires.entrySet()) {
String src = entry.getKey();
List<String> dests = entry.getValue();
Integer srcVal = getAnySignal(src, localSignal, outerSig, subMap);
if(srcVal == null) continue;
for(String d : dests) localSignal.put(d, srcVal);
}
for(Gate g : innerGates) {
Integer val = singleGateCalc(g, localSignal, outerSig, subMap);
if(val != null) {
String gateOut = g.getName() + "-0";
localSignal.put(gateOut, val);
}
}
evaluated = true;
return null;
}
private Integer getAnySignal(String pin, Map<String, Integer> local, Map<String, Integer> outer, Map<Integer, SubCircuit> subMap) {
if(local.containsKey(pin)) return local.get(pin);
if(outer.containsKey(pin)) return outer.get(pin);
if(pin.startsWith("C")) {
String[] sp = pin.split("-", 2);
int scId = Integer.parseInt(sp[0].substring(1));
SubCircuit sc = subMap.get(scId);
if(sc == null) return null;
sc.eval(outer, subMap);
return sc.localSignal.get(sp[1]);
}
return null;
}
private Integer singleGateCalc(Gate gate, Map<String, Integer> sig, Map<String, Integer> outer, Map<Integer, SubCircuit> subMap) {
char t = gate.getType();
int num = gate.getInputNum();
List<Integer> in = new ArrayList<>();
for(int i=1; i<=num; i++) {
String p = gate.getName() + "-" + i;
Integer v = getAnySignal(p, sig, outer, subMap);
if(v == null) return null;
in.add(v);
}
int res = 0;
if(t=='A') {
res=1;
for(int v:in) if(v==0) res=0;
}else if(t=='O') {
res=0;
for(int v:in) if(v==1) res=1;
}else if(t=='N') {
res=1-in.get(0);
}else if(t=='X') {
res=in.get(0)^in.get(1);
}else if(t=='Y') {
res=in.get(0).equals(in.get(1))?1:0;
}
gate.setOutput(res);
return res;
}
}
class Circuit{
private List<String> pinNames;
private List<Integer> pinValues;
private List<String> sourceList;
private List<List<String>> targetList;
private List<Gate> allGate;
private List<Gate> andGate;
private List<Gate> orGate;
private List<Gate> notGate;
private List<Gate> xorGate;
private List<Gate> xnorGate;
private List<Gate> triGate;
private List<Gate> decoderGate;
private List<Gate> muxGate;
private List<Gate> demuxGate;
private Map<String,Integer> decOutMap;
private Map<String,char[]> demuxOutMap;
public Map<Integer, SubCircuit> subCircuitMap = new TreeMap<>();
public String errorMsg = null;
public Map<String, String> pinDriverMap = new HashMap<>();
public List<Gate> allSubGates = new ArrayList<>();
public Map<String, String> subPortBind = new HashMap<>();
public boolean inSubParse = false;
public Set<String> allDestPins=new HashSet<>();
public Circuit(){
pinNames=new ArrayList<>();
pinValues=new ArrayList<>();
sourceList=new ArrayList<>();
targetList=new ArrayList<>();
allGate=new ArrayList<>();
andGate=new ArrayList<>();
orGate=new ArrayList<>();
notGate=new ArrayList<>();
xorGate=new ArrayList<>();
xnorGate=new ArrayList<>();
triGate=new ArrayList<>();
decoderGate=new ArrayList<>();
muxGate=new ArrayList<>();
demuxGate=new ArrayList<>();
decOutMap=new HashMap<>();
demuxOutMap=new HashMap<>();
}
private void addGateToTypeList(Gate gate){
char t=gate.getType();
if(t=='A')andGate.add(gate);
else if(t=='O')orGate.add(gate);
else if(t=='N')notGate.add(gate);
else if(t=='X')xorGate.add(gate);
else if(t=='Y')xnorGate.add(gate);
else if(t=='S')triGate.add(gate);
else if(t=='M')decoderGate.add(gate);
else if(t=='Z')muxGate.add(gate);
else if(t=='F')demuxGate.add(gate);
}
public void savePin(String name,int val){
pinNames.add(name);
pinValues.add(val);
}
public void savePinNull(String name){
pinNames.add(name);
pinValues.add(null);
}
public Integer searchInputPin(String pin){
for(int i=0;i<pinNames.size();i++){
if(pinNames.get(i).equals(pin)){
return pinValues.get(i);
}
}
return null;
}
public String findDriveSource(String targetPin){
for(int i=0;i<sourceList.size();i++){
List<String> targets=targetList.get(i);
for(String p:targets){
if(p.equals(targetPin)){
return sourceList.get(i);
}
}
}
if(subPortBind.containsKey(targetPin)){
return subPortBind.get(targetPin);
}
return null;
}
public Gate searchGate(String gateName){
for(Gate g:allGate){
if(g.getName().equals(gateName)){
return g;
}
}
return null;
}
public void readInputLine(String line){
int idx=6;
while(idx<line.length()&&line.charAt(idx)==' ')idx++;
String cur="";
List<String> s=new ArrayList<>();
while(idx<line.length()){
char c=line.charAt(idx);
if(c==' '){
boolean b=!cur.equals("");
if(b){
s.add(cur);
cur="";
}
}else{
cur+=c;
}
idx++;
}
boolean b=!cur.equals("");
if(b)s.add(cur);
for(String item:s){
int m=0;
while(m<item.length()&&item.charAt(m)!='-')m++;
String nm="";
for(int k=0;k<m;k++)nm+=item.charAt(k);
int num=item.charAt(m+1)-'0';
savePin(nm,num);
}
}
public List<String> splitBracketLine(String line) {
List<String> s=new ArrayList<>();
String cur="";
for(int i=1;i<line.length()-1;i++){
char c=line.charAt(i);
if(c==' '){
if(!cur.isEmpty()){
s.add(cur);
cur="";
}
}else cur+=c;
}
if(!cur.isEmpty()) s.add(cur);
return s;
}
public Gate createGateSingle(String pinStr) {
int p = pinStr.indexOf('-');
if(p == -1) return null;
String nm = pinStr.substring(0,p);
if(searchGate(nm) != null) return null;
char t=nm.charAt(0);
Gate gate=null;
if(t=='A'||t=='O'){
int l=nm.indexOf('('), r=nm.indexOf(')');
int ic=Integer.parseInt(nm.substring(l+1,r));
int gid=Integer.parseInt(nm.substring(r+1));
gate=new Gate(nm,t,ic,gid);
}else if(t=='N'||t=='X'||t=='Y'){
int gid=Integer.parseInt(nm.substring(1));
int ic = (t=='X'||t=='Y')?2:1;
gate=new Gate(nm,t,ic,gid);
}
if(gate!=null){
if(!inSubParse){
allGate.add(gate);
addGateToTypeList(gate);
}
}
return gate;
}
public void readConnectLine(String line){
if(errorMsg != null) return;
List<String> s = splitBracketLine(line);
String bracketRaw = line.trim();
int sourceCount = 0;
int srcIdx = -1;
int targetCount = 0;
for(int i=0;i<s.size();i++){
String tok = s.get(i);
if(tok.endsWith("-0") || !tok.contains("-"))
{
sourceCount++;
srcIdx = i;
}
else
{
targetCount++;
}
}
if(sourceCount >= 2){
errorMsg = String.format("ERROR: %s include more than one input", bracketRaw);
return;
}
if(sourceCount == 0){
errorMsg = String.format("ERROR: %s include none input", bracketRaw);
return;
}
if(targetCount == 0){
errorMsg = String.format("ERROR: %s include none output", bracketRaw);
return;
}
if(srcIdx != 0){
errorMsg = String.format("ERROR: %s input and output sequence error", bracketRaw);
return;
}
String src = s.get(0);
List<String> tar=new ArrayList<>();
for(int i=1;i<s.size();i++) tar.add(s.get(i));
for(String t:tar){
if(allDestPins.contains(t)){
errorMsg = String.format("ERROR: %s input signal conflict", t);
return;
}
allDestPins.add(t);
if(t.startsWith("C") && t.contains("-")){
subPortBind.put(t, src);
continue;
}
pinDriverMap.put(t, src);
}
sourceList.add(src);
targetList.add(tar);
for(String t:tar){
if(t.contains("-") && !t.startsWith("C")) createGateSingle(t);
}
}
public int parseSubCircuit(List<String> buffer, int ptr) {
String head = buffer.get(ptr++);
int cid = Integer.parseInt(head.substring(1, head.length()-1));
SubCircuit sc = new SubCircuit(cid);
inSubParse = true;
while(ptr < buffer.size()) {
String line = buffer.get(ptr).trim();
ptr++;
if(line.equals("endc")) break;
if(line.startsWith("INPUT:")) {
String part = line.substring(6).trim();
sc.subInputs.addAll(Arrays.asList(part.split(" +")));
} else if(line.startsWith("OUT:")) {
String part = line.substring(4).trim();
sc.subOutputs.addAll(Arrays.asList(part.split(" +")));
} else if(line.startsWith("[") && line.endsWith("]")) {
List<String> tokens = splitBracketLine(line);
String src = tokens.get(0);
List<String> targets = tokens.subList(1, tokens.size());
sc.innerWires.computeIfAbsent(src, k->new ArrayList<>()).addAll(targets);
for(String t : targets) {
if(t.contains("-")) {
Gate g = createGateSingle(t);
if(g != null){
sc.addChild(g);
allSubGates.add(g);
}
}
}
}
}
inSubParse = false;
subCircuitMap.put(cid, sc);
return ptr;
}
public Integer getTopSignal(String pin, Map<String,Integer> outerSignal, Map<Integer,SubCircuit> subMap){
if(outerSignal.containsKey(pin)){
return outerSignal.get(pin);
}
Integer inputVal = searchInputPin(pin);
if(inputVal != null){
outerSignal.put(pin, inputVal);
return inputVal;
}
String src = findDriveSource(pin);
if(src == null) return null;
if(src.startsWith("C")){
String[] sp = src.split("-",2);
int scId = Integer.parseInt(sp[0].substring(1));
SubCircuit sc = subMap.get(scId);
if(sc == null) return null;
sc.eval(outerSignal, subMap);
Integer subVal = sc.localSignal.get(sp[1]);
if(subVal != null){
outerSignal.put(pin, subVal);
}
return subVal;
}
int dash = src.indexOf('-');
if(dash == -1){
Integer val = getTopSignal(src, outerSignal, subMap);
outerSignal.put(pin, val);
return val;
}
String gateName = src.substring(0, dash);
Gate g = searchGate(gateName);
if(g == null) return null;
calcTopGate(g, outerSignal, subMap);
Integer gateOut = g.getOutput();
outerSignal.put(pin, gateOut);
return gateOut;
}
public void calcTopGate(Gate gate, Map<String,Integer> outerSignal, Map<Integer,SubCircuit> subMap){
if(gate.getOutput() != null) return;
String gName = gate.getName();
char t = gate.getType();
List<Integer> in = new ArrayList<>();
int num = gate.getInputNum();
for(int i=1;i<=num;i++){
String p = gName + "-" + i;
Integer v = getTopSignal(p, outerSignal, subMap);
if(v == null) return;
in.add(v);
}
int res = 0;
if(t=='A'){
res=1;
for(int v:in) if(v==0) res=0;
}else if(t=='O'){
res=0;
for(int v:in) if(v==1) res=1;
}else if(t=='N'){
res=1-in.get(0);
}else if(t=='X'){
res=in.get(0)^in.get(1);
}else if(t=='Y'){
res=in.get(0).equals(in.get(1))?1:0;
}
gate.setOutput(res);
}
public void computeAllTopGate(Map<String,Integer> outerSignal, Map<Integer,SubCircuit> subMap){
for(Gate g : allGate){
calcTopGate(g, outerSignal, subMap);
}
}
public void sortGate(){
Collections.sort(andGate);
Collections.sort(orGate);
Collections.sort(notGate);
Collections.sort(xorGate);
Collections.sort(xnorGate);
Collections.sort(triGate);
Collections.sort(decoderGate);
Collections.sort(muxGate);
Collections.sort(demuxGate);
}
public void printAllResult() {
Map<String,Integer> outerSignal = new HashMap<>();
Set<String> printed = new HashSet<>();
for(int i=0;i<pinNames.size();i++){
String name = pinNames.get(i);
Integer val = pinValues.get(i);
if(val != null) outerSignal.put(name,val);
}
for(var entry : subPortBind.entrySet()){
String portFull = entry.getKey();
String srcName = entry.getValue();
Integer srcVal = getTopSignal(srcName, outerSignal, subCircuitMap);
if(srcVal != null){
outerSignal.put(portFull, srcVal);
}
}
for(int round=0;round<10;round++){
for(SubCircuit sc : subCircuitMap.values()){
sc.evaluated = false;
}
for(SubCircuit sc : subCircuitMap.values()){
sc.eval(outerSignal, subCircuitMap);
for(var entry : sc.localSignal.entrySet()){
String fullName = "C"+sc.cid+"-"+entry.getKey();
outerSignal.put(fullName, entry.getValue());
}
}
}
for(SubCircuit sc : subCircuitMap.values()){
List<Gate> subGates = sc.innerGates;
subGates.sort((g1,g2)->{
char t1=g1.getType(),t2=g2.getType();
char[] order = {'A','O','N','X','Y'};
int o1=0,o2=0;
for(int i=0;i<order.length;i++){
if(order[i]==t1)o1=i;
if(order[i]==t2)o2=i;
}
if(o1 != o2) return o1-o2;
return g1.compareTo(g2);
});
for(Gate g : subGates){
if(g.getOutput() != null){
String gateOut = "C"+sc.cid+"-"+g.getName()+"-0";
if(!printed.contains(gateOut)){
printed.add(gateOut);
System.out.printf("%s:%d%n", gateOut, g.getOutput());
}
}
}
}
computeAllTopGate(outerSignal, subCircuitMap);
sortGate();
for(Gate g:andGate)if(g.getOutput()!=null)System.out.println(g.getName()+"-0:"+g.getOutput());
for(Gate g:orGate)if(g.getOutput()!=null)System.out.println(g.getName()+"-0:"+g.getOutput());
for(Gate g:notGate)if(g.getOutput()!=null)System.out.println(g.getName()+"-0:"+g.getOutput());
for(Gate g:xorGate)if(g.getOutput()!=null)System.out.println(g.getName()+"-0:"+g.getOutput());
for(Gate g:xnorGate)if(g.getOutput()!=null)System.out.println(g.getName()+"-0:"+g.getOutput());
for(Gate g:triGate){
Integer v=getTopSignal(g.getName()+"-2", outerSignal, subCircuitMap);
if(v!=null){
System.out.println(g.getName()+"-2:"+v);
}
}
for(Gate g:decoderGate){
Integer zeroIdx=decOutMap.get(g.getName());
if(zeroIdx!=null){
System.out.println(g.getName()+":"+zeroIdx);
}
}
for(Gate g:muxGate){
Integer v = g.getOutput();
if(v!=null){
int outNo=g.getCtrlNum()+g.getInputNum();
System.out.println(g.getName()+"-"+outNo+":"+v);
}
}
for(Gate g:demuxGate){
char[] arr=demuxOutMap.get(g.getName());
if(arr!=null){
System.out.println(g.getName()+":"+new String(arr));
}
}
}
}


类间关系比较复杂,题目难度较难。
踩坑心得:
1.一个连接信息中包含两个或多个输入,输出:ERROR:“连接信息”+“英文空格”+include more than one input 例如: INPUT: A-1 B-1 [A B A2-1] 应输出: ERROR: [A B A2-1] include more than one input 2.一个连接信息中没有输入信息,输出:ERROR:“连接信息”+“英文空格”+include none input 例如: INPUT: A-1 B-1 [C1-1 C2-1] 应输出: ERROR: [C1-1 C2-1] include none input 注意:C1-1 C2-1引脚是元件的输入引脚,但作为连接信息,元件的输入引脚属于连接系统的输出,所以是none input 3.一个连接信息中没有输出,输出:ERROR:“连接信息”+“英文空格”+include none output 例如: INPUT: A-1 B-1 [A] 应输出:ERROR: [A] include none output 4.一个连接信息中输入输出写反,输出:ERROR:“连接信息”+“英文空格”+input and output sequence error 例如: INPUT: A-1 B-1 [A2-1 A] 应输出:ERROR: [A2-1 A] input and output sequence error 5.一个输入引脚接受中来自多个不同输出的信号,输出:ERROR:“输入引脚”+“英文空格”+input signal conflict 例如: INPUT: A-1 B-1 [A A2-1] [B A2-1] 应输出:ERROR: A2-1 input signal conflict 注:如果一条输入出现了多种异常,按以上异常先后顺序为优先级,顺序靠前者优先级越高,最后输出优先级最高的异常输出。 当电路输入信息中多条输入都包含异常,只处理排在最前面的异常信息。
在处理这些异常时,觉得自己把这些不同的异常处理弄混了,导致没有多与的时间思考,只是过了那些用例。
心得: 以后在处理问题会仔仔细细的看好题目要求。
总结:
通过这三次的题目,类与类之间的关系处理已比较熟练,能快速的理清题目中所包含的所有类间关系并完成代码。我觉得还需要进一步学习和研究的是一些代码实现的应用,熟练掌握对它们的操作,教师授课很好,作业难度比较难,课程推进速度合适,实验难度还可以,但是建议哪个“ : ”等的输出可不可以说一声是中文还是英文,改错的时候真的有点烦。

浙公网安备 33010602011771号