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());
    }
}

  

image

 

image

 代码的实现比较难,花了不是时间完成。

 

 

踩坑心得:没有踩坑,但是还是有一些代码上的语法错误,问题不是回答,自己解决了这些问题。

 

 

心得:通过这个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));
            }
        }
    }
}

  

image

 

image

 

相比与上一次代码这次代码的实现更为困难

 

踩坑心得:在完成代码后提交后没有满分,然后自己直接考虑是不是自己的代码在一些方面的处理存在bug,但是经过了很长时间的努力修改,还是没有得到满分。

 

心得: 虽然代码的每一个测试用例都过了,但是还是没有得到满分,建议可以给一点提示。

 

 

第三次作业.

 

1. 目标: 采用组合模式,将子电路和电路元件作为抽象的元件类的子类,即可以将子电路看作一种组合型的电路元件。组合模式通用类图如下:

 

image

 图中可将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));
        }
    }
}
}

  

image

 

image

 

类间关系比较复杂,题目难度较难。

 

 踩坑心得:

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


注:如果一条输入出现了多种异常,按以上异常先后顺序为优先级,顺序靠前者优先级越高,最后输出优先级最高的异常输出。

当电路输入信息中多条输入都包含异常,只处理排在最前面的异常信息。

  在处理这些异常时,觉得自己把这些不同的异常处理弄混了,导致没有多与的时间思考,只是过了那些用例。

 

 心得: 以后在处理问题会仔仔细细的看好题目要求。

 

总结:

通过这三次的题目,类与类之间的关系处理已比较熟练,能快速的理清题目中所包含的所有类间关系并完成代码。我觉得还需要进一步学习和研究的是一些代码实现的应用,熟练掌握对它们的操作,教师授课很好,作业难度比较难,课程推进速度合适,实验难度还可以,但是建议哪个“ : ”等的输出可不可以说一声是中文还是英文,改错的时候真的有点烦。

 

posted @ 2026-06-24 18:55  hzj111  阅读(3)  评论(0)    收藏  举报