OO第二次作业

三次作业实现
一、PTA4

  • 题干内容
    设计实现答题程序,模拟一个小型的测试,要求输入题目信息、试卷信息、答题信息、学生信息、删除题目信息,根据输入题目信息中的标准答案判断答题的结果。本题在答题判题程序-3基础上新增的内容统一附加在输出格式说明之后,用粗体标明。
    输入格式:
    程序输入信息分五种,信息可能会打乱顺序混合输入。
    1、题目信息
    题目信息为独行输入,一行为一道题,多道题可分多行输入。
    格式:"#N:"+题目编号+" "+"#Q:"+题目内容+" "#A:"+标准答案
    格式约束:
        1、题目的输入顺序与题号不相关,不一定按题号顺序从小到大输入。
        2、允许题目编号有缺失,例如:所有输入的题号为1、2、5,缺少其中的3号题。此种情况视为正常。
    样例:#N:1 #Q:1+1= #A:2
         #N:2 #Q:2+2= #A:4
    
    2、试卷信息
    试卷信息为独行输入,一行为一张试卷,多张卷可分多行输入数据。
    格式:"#T:"+试卷号+" "+题目编号+"-"+题目分值+" "+题目编号+"-"+题目分值+...
    格式约束:
       题目编号应与题目信息中的编号对应。
       一行信息中可有多项题目编号与分值。 
    样例:#T:1 3-5 4-8 5-2
    
    3、学生信息
    学生信息只输入一行,一行中包括所有学生的信息,每个学生的信息包括学号和姓名,格式如下。
    格式:"#X:"+学号+" "+姓名+"-"+学号+" "+姓名....+"-"+学号+" "+姓名  
    格式约束:
        答案数量可以不等于试卷信息中题目的数量,没有答案的题目计0分,多余的答案直接忽略,答案之间以英文空格分隔。
    样例:
           #S:1 #A:5 #A:22
           1是试卷号 
           5是1号试卷的顺序第1题的题目答案    
    
    4、答卷信息
    答卷信息按行输入,每一行为一张答卷的答案,每组答案包含某个试卷信息中的题目的解题答案,答案的顺序号与试 卷信息中的题目顺序相对应。答卷中:
    格式:"#S:"+试卷号+" "+学号+" "+"#A:"+试卷题目的顺序号+"-"+答案内容+...
    格式约束:
         答案数量可以不等于试卷信息中题目的数量,没有答案的题目计0分,多余的答案直接忽略,答案之间以英文空格分隔。
         答案内容可以为空,即””。
         答案内容中如果首尾有多余的空格,应去除后再进行判断。
         答卷信息中仅包含试卷号、学号,而没有后续内容的,视为一张空白卷,为有效信息,不做格式错误处理。
    样例:
         #T:1 1-5 3-2 2-5 6-9 4-10 7-3
         #S:1 20201103 #A:2-5 #A:6-4
         1是试卷号
         20201103是学号
         2-5中的2是试卷中顺序号,5是试卷第2题的答案,即T中3-2的答案 
         6-4中的6是试卷中顺序号,4是试卷第6题的答案,即T中7-3的答案 
    注意:不要混淆顺序号与题号
    
    5、删除题目信息
    删除题目信息为独行输入,每一行为一条删除信息,多条删除信息可分多行输入。该信息用于删除一道题目信息,题目被删除之后,引用该题目的试卷依然有效,但被删除的题目将以0分计,同时在输出答案时,题目内容与答案改为一条失效提示,例如:”the question 2 invalid~0”
    格式:"#D:N-"+题目号
    格式约束:
           题目号与第一项”题目信息”中的题号相对应,不是试卷中的题目顺序号。
           本题暂不考虑删除的题号不存在的情况。  
    样例:
    #N:1 #Q:1+1= #A:2
    #N:2 #Q:2+2= #A:4
    #T:1 1-5 2-8
    #X:20201103 Tom-20201104 Jack
    #S:1 20201103 #A:1-5 #A:2-4
    #D:N-2
    end 
    
    输出:
    alert: full score of test paper1 is not 100 points
    1+1=~5~false
    the question 2 invalid~0
    20201103 Tom: 0 0~0
    
    答题信息以一行"end"标记结束,"end"之后的信息忽略。
    输出格式:
    1、试卷总分警示
    该部分仅当一张试卷的总分分值不等于100分时作提示之用,试卷依然属于正常试卷,可用于后面的答题。如果总分等于100 分,该部分忽略,不输出。
    格式:"alert: full score of test paper"+试卷号+" is not 100 points"
    约束:有多张试卷时,按输入信息的先后顺序输出警示。
    样例:alert: full score of test paper2 is not 100 points
    2、答卷信息
    一行为一道题的答题信息,根据试卷的题目的数量输出多行数据。
    格式:题目内容+""+答案++""+判题结果(true/false)
    约束:如果输入的答案信息少于试卷的题目数量,每一个缺失答案的题目都要输出"answer is null" 。
    样例:
    answer is null
    3+2=5true
    4+6=22false.
    answer is null
    3、判分信息
    判分信息为一行数据,是一条答题记录所对应试卷的每道小题的计分以及总分,计分输出的先后顺序与题目题号相对应。
    格式:学号+" "+姓名+": "+题目得分+" "+....+题目得分+"~"+总分
    格式约束:
         1、没有输入答案的题目、被删除的题目、答案错误的题目计0分
         2、判题信息的顺序与输入答题信息中的顺序相同
    样例:20201103 Tom: 0 0~0
         根据输入的答卷的数量以上2、3项答卷信息与判分信息将重复输出。
    
    4、被删除的题目提示信息
    当某题目被试卷引用,同时被删除时,答案中输出提示信息。样例见第5种输入信息“删除题目信息”。
    5、题目引用错误提示信息
    试卷错误地引用了一道不存在题号的试题,在输出学生答案时,提示”non-existent question~”加答案。例如:
    输入:
    #N:1 #Q:1+1= #A:2
    #T:1 3-8
    #X:20201103 Tom-20201104 Jack-20201105 Www
    #S:1 20201103 #A:1-4
    end
    输出:
    alert: full score of test paper1 is not 100 points
    non-existent question~0
    20201103 Tom: 0~0
    
    如果答案输出时,一道题目同时出现答案不存在、引用错误题号、题目被删除,只提示一种信息,答案不存在的优先级最高,例如:
    输入:
    #N:1 #Q:1+1= #A:2
    #T:1 3-8
    #X:20201103 Tom-20201104 Jack-20201105 Www
    #S:1 20201103
    end
    输出:
    alert: full score of test paper1 is not 100 points
    answer is null
    20201103 Tom: 0~0
    
    6、格式错误提示信息
    输入信息只要不符合格式要求,均输出”wrong format:”+信息内容。
    例如:wrong format:2 #Q:2+2= #4
    7、试卷号引用错误提示输出
    如果答卷信息中试卷的编号找不到,则输出”the test paper number does not exist”,答卷中的答案不用输出,参见样例8。
    8、学号引用错误提示信息
    如果答卷中的学号信息不在学生列表中,答案照常输出,判分时提示错误。参见样例9。
    本次作业新增内容:
    1、输入选择题题目信息
    题目信息为独行输入,一行为一道题,多道题可分多行输入。
    格式:"#Z:"+题目编号+" "+"#Q:"+题目内容+" "#A:"+标准答案
    格式基本的约束与一般的题目输入信息一致。
    
    新增约束:标准答案中如果包含多个正确答案(多选题),正确答案之间用英文空格分隔。
    例如:
     #Z:2 #Q:宋代书法有苏黄米蔡四家,分别是: #A:苏轼 黄庭坚 米芾 蔡襄
    
    多选题输出:
    输出格式与一般答卷题目的输出一致,判断结果除了true、false,增加一项”partially correct”表示部分正确。
    多选题给分方式:
    答案包含所有正确答案且不含错误答案给满分;
    包含一个错误答案或完全没有答案给0分;
    包含部分正确答案且不含错误答案给一半分,如果一半分值为小数,按截尾规则只保留整数部分。
    
    例如:
    #N:1 #Q:1+1= #A:2
    #Z:2 #Q:党十八大报告提出要加强()建设。A 政务诚信 B 商务诚信 C社会诚信 D司法公信 #A:A B C D
    #T:1 1-5 2-9
    #X:20201103 Tom
    #S:1 20201103 #A:1-5 #A:2-A C
    end
    输出:
    alert: full score of test paper1 is not 100 points
    1+1=~5~false
    党十八大报告提出要加强()建设。A 政务诚信 B 商务诚信 C社会诚信 D司法公信~A C~partially correct
    20201103 Tom: 0 4~4
    
    2、输入填空题题目信息
    题目信息为独行输入,一行为一道题,多道题可分多行输入。
    格式:"#K:"+题目编号+" "+"#Q:"+题目内容+" "#A:"+标准答案
    格式基本的约束与一般的题目输入信息一致。
    例如:#K:2 #Q:古琴在古代被称为: #A:瑶琴或七弦琴
    
    填空题输出:
    输出格式与一般答卷题目的输出一致,判断结果除了true、false,增加一项”partially correct”表示部分正确。
    填空题给分方式:
    答案与标准答案内容完全匹配给满分,包含一个错误字符或完全没有答案给0分,包含部分正确答案且不含错误字符给一半分,如果一半分值为小数,按截尾规则只保留整数部分。
    例如:
    #N:1 #Q:1+1= #A:2
    #K:2 #Q:古琴在古代被称为: #A:瑶琴或七弦琴
    #T:1 1-5 2-10
    #X:20201103 Tom
    #S:1 20201103 #A:1-5 #A:2-瑶琴
    end
    输出:
    alert: full score of test paper1 is not 100 points
    1+1=~5~false
    古琴在古代被称为:~瑶琴~partially correct
    20201103 Tom: 0 5~5
    
    3、输出顺序变化
    只要是正确格式的信息,可以以任意的先后顺序输入各类不同的信息。比如试卷可以出现在题目之前,删除题目的信息可以出现在题目之前等。
    例如:
    #T:1 1-5 2-10
    #N:1 #Q:1+1= #A:2
    #K:2 #Q:古琴在古代被称为: #A:瑶琴或七弦琴
    #X:20201103 Tom
    #S:1 20201103 #A:1-5 #A:2-古筝
    end
    输出:
    alert: full score of test paper1 is not 100 points
    1+1=~5~false
    古琴在古代被称为:~古筝~false
    20201103 Tom: 0 0~0
    
    4、多张试卷信息
    本题考虑多个同学有多张不同试卷的答卷的情况。输出顺序优先级为学号、试卷号,按从小到大的顺序先按学号排序,再按试卷号。
    例如:
    #T:1 1-5 2-10
    #T:2 1-8 2-21
    #N:1 #Q:1+1= #A:2
    #S:2 20201103 #A:1-2 #A:2-古筝
    #S:1 20201103 #A:1-5 #A:2-瑶琴或七弦琴
    #S:1 20201104 #A:1-2 #A:2-瑟
    #S:2 20201104 #A:1-5 #A:2-七弦琴
    #X:20201103 Tom-20201104 Jack
    #K:2 #Q:古琴在古代被称为: #A:瑶琴或七弦琴
    end
    输出:
    alert: full score of test paper1 is not 100 points
    alert: full score of test paper2 is not 100 points
    1+1=~5~false
    古琴在古代被称为:~瑶琴或七弦琴~true
    20201103 Tom: 0 10~10
    1+1=~2~true
    古琴在古代被称为:~古筝~false
    20201103 Tom: 8 0~8
    1+1=~2~true
    古琴在古代被称为:~瑟~false
    20201104 Jack: 5 0~5
    1+1=~5~false
    古琴在古代被称为:~七弦琴~partially correct
    20201104 Jack: 0 10~10
    
    新增的题目异常情况的处理与一般题目相同,具体样例参考上一次大作业的样例说明:
    输入样例1:
    多选题测试,不含删除。例如:
    #N:1 #Q:1+1= #A:2
    #Z:2 #Q:党十八大报告提出要加强()建设。A 政务诚信 B 商务诚信 C社会诚信 D司法公信 #A:A B C D
    #T:1 1-5 2-9
    #X:20201103 Tom
    #S:1 20201103 #A:1-5 #A:2-A C 
    end
    
    输出样例1:
    在这里给出相应的输出。例如:
    alert: full score of test paper1 is not 100 points
    1+1=~5~false
    党十八大报告提出要加强()建设。A 政务诚信 B 商务诚信 C社会诚信 D司法公信~A C~partially correct
    20201103 Tom: 0 4~4
    
    输入样例2:
    填空题测试,不含删除。例如:
    #N:1 #Q:1+1= #A:2
    #K:2 #Q:古琴在古代被称为: #A:瑶琴或七弦琴
    #T:1 1-5 2-10
    #X:20201103 Tom
    #S:1 20201103 #A:1-5 #A:2-瑶琴
    end
    
    输出样例2:
    在这里给出相应的输出。例如:
    alert: full score of test paper1 is not 100 points
    1+1=~5~false
    古琴在古代被称为:~瑶琴~partially correct
    20201103 Tom: 0 5~5
    
    输入样例3:
    乱序测试,不含删除。例如:
    #T:1 1-5 2-10
    #N:1 #Q:1+1= #A:2
    #K:2 #Q:古琴在古代被称为: #A:瑶琴或七弦琴
    #X:20201103 Tom
    #S:1 20201103 #A:1-5 #A:2-古筝
    end
    
    输出样例3:
    在这里给出相应的输出。例如:
    alert: full score of test paper1 is not 100 points
    1+1=~5~false
    古琴在古代被称为:~古筝~false
    20201103 Tom: 0 0~0
    
    输入样例4:
    两个同学多张不同试卷的答卷,不含删除。例如:
    #T:1 1-5 2-10
    #T:2 1-8 2-21
    #N:1 #Q:1+1= #A:2
    #S:2 20201103 #A:1-2 #A:2-古筝
    #S:1 20201104 #A:1-2 #A:2-瑟
    #S:1 20201103 #A:1-5 #A:2-瑶琴或七弦琴
    #S:2 20201104 #A:1-5 #A:2-七弦琴
    #X:20201103 Tom-20201104 Jack
    #K:2 #Q:古琴在古代被称为: #A:瑶琴或七弦琴
    end
    
    输出样例4:
    在这里给出相应的输出。例如:
    alert: full score of test paper1 is not 100 points
    alert: full score of test paper2 is not 100 points
    1+1=~5~false
    古琴在古代被称为:~瑶琴或七弦琴~true
    20201103 Tom: 0 10~10
    1+1=~2~true
    古琴在古代被称为:~古筝~false
    20201103 Tom: 8 0~8
    1+1=~2~true
    古琴在古代被称为:~瑟~false
    20201104 Jack: 5 0~5
    1+1=~5~false
    古琴在古代被称为:~七弦琴~partially correct
    20201104 Jack: 0 10~10
    
  • 设计与分析
    这一次怎么说呢,其实已经没有什么太大的设计了,都是在以前的基础上往上加内容,其实这一次作业做的迷迷糊糊,没有很清楚的思路,主要是借鉴前人大佬的经验,加以修改,在这里就不多说了。而且这一次作业得分为0,说的也实在是在误人子弟。
  • 踩坑心得
    关于这一次的踩坑心得呢,其实这么说吧,听从一个大佬的建议使用了TreeSet来储存,还涉及到了接口(当时还没有开始学),但是由于自身层次不够,对于这个都不是很清楚,花费了大量的时间去学习这些陌生的知识,并且掌握并不透彻,属于是在无效学习了,可能是导致后续一直没有办法完成程序的很大原因。总的来说就是还是要量力而行吧,别太好高骛远,适合别人的方法未必适合自己,是这么说的。
  • 代码实现
点击查看代码
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.HashMap;
import java.util.TreeSet;
class Question{
    String num;
    String concent;
    int value;
    boolean effect=true;//有效性
    int iswhich;
    Question(){}
    Question(String num,String concent,int iswhich){
        this.num=num;
        this.concent=concent;
        this.iswhich=iswhich;
    }
    void setIswhich(int iswhich){
        this.iswhich=iswhich;
    }
    int getIswhich(){
        return this.iswhich;
    }
    void setNum(String num){
        this.num=num;
    }
    String getNum(){
        return this.num;
    }
    void setConcent(String concent){
        this.concent=concent;
    }
    String getConcent(){
        return this.concent;
    }
    void setValue(int value){
        this.value=value;
    }
    int getValue(){
        return this.value;
    }
    void setEffect(boolean effect){
        this.effect=effect;
    }
    boolean getEffect(){
        return this.effect;
    }
}
class mulityQuestion extends Question{//多选
    String[] standardAnswer;
    //int iswhich=1;
    mulityQuestion(){}
    mulityQuestion(String num,String concent,String[] standardAnswer){
        super(num,concent,1);
        this.standardAnswer=standardAnswer;
    }
    void setStandardAnswer(String[] standardAnswer){
        this.standardAnswer=standardAnswer;
    }
    String[] getStandardAnswer(){
        return this.standardAnswer;
    }
    // void setIswhich(int iswhich){
    //     this.iswhich=iswhich;
    // }
    // int getIswhich(){
    //     return this.iswhich;
    // }
    void JudgeMulityAnswer(MulityAnswer answer){
        boolean[] isTrue=new boolean[answer.getConcent().length];
        for(int i=0;i<answer.getConcent().length;i++){
            for(int j=0;j<this.standardAnswer.length;j++){
                if(answer.getConcent()[i].equals(this.standardAnswer[j]))
                    isTrue[i]=true;
            }
            if(isTrue[i]==false){
                answer.setIstrue(-1);
                return ;
            }
        }
        if(answer.getConcent().length<this.standardAnswer.length)
            answer.setIstrue(0);
        else
            answer.setIstrue(1);
    }
}
class fillQuestion extends Question{//填空
    String standardAnswer;
    //int iswhich=0;
    fillQuestion(){}
    fillQuestion(String num,String concent,String standardAnswer){
        super(num,concent,0);
        this.standardAnswer=standardAnswer;
    }
    void setStandardAnswer(String standardAnswer){
        this.standardAnswer=standardAnswer;
    }
    String getStandardAnswer(){
        return this.standardAnswer;
    }
    // void setIswhich(int iswhich){
    //     this.iswhich=iswhich;
    // }
    // int getIswhich(){
    //     return this.iswhich;
    // }
    void JudgeFillAnswer(FillAnswer answer){
        if(this.standardAnswer.matches(".*"+answer.getConcent()+".*")){
            if(this.standardAnswer.equals(answer.getConcent()))
                answer.setIstrue(1);
            else
                answer.setIstrue(0);
        }
        else
            answer.setIstrue(-1);
    }
}
class commonQuestion extends Question{
    String standardAnswer;
    //int iswhich=-1;
    commonQuestion(){}
    commonQuestion(String num,String concent,String standardAnswer){
        super(num,concent,-1);
        this.standardAnswer=standardAnswer;
    }
    void setStandardAnswer(String standardAnswer){
        this.standardAnswer=standardAnswer;
    }
    String getStandardAnswer(){
        return this.standardAnswer;
    }
    void JudgeCommonAnswer(CommonAnswer answer){
        if(this.standardAnswer.equals(answer.getConcent()))
            answer.setIstrue(1);
        else
            answer.setIstrue(-1);
    }
    // void setIswhich(int iswhich){
    //     this.iswhich=iswhich;
    // }
    // int getIswhich(){
    //     return this.iswhich;
    // }
}
// class testQuestion{
//     Question question;
//     int value;
//     boolean effect=true;//有效性
//     testQuestion(){}
//     testQuestion(Question question,int value){
//         this.question=question;
//         this.value=value;
//         this.effect=true;
//     }
//     void setValue(int value){
//         this.value=value;
//     }
//     int getValue(){
//         return this.value;
//     }
//     void setEffect(boolean effect){
//         this.effect=effect;
//     }
//     boolean getEffect(){
//         return this.effect;
//     }
// }
class Papper{
    String num;
    HashMap<Integer,Question> question=new HashMap<>();//Integer是题目顺序
    Papper(){}
    Papper(String num){
        this.num=num;
    }
    HashMap<Integer,Question> getHashMap(){
        return this.question;
    }
    void setQuestion(Integer key,Question value){
        question.put(key,value);
    }
    Question getQuestion(Integer key){
        return question.get(key);
    }
    void setNum(String num){
        this.num=num;
    }
    String getNum(){
        return this.num;
    }
    int allScore(){
        int sum=0;
        for(Question value:question.values()){
            if(value!=null)
                if(value.getEffect())
                    sum+=value.getValue();
        }
        return sum;
    }
    
}
// class Student{
//     String stuNum;
//     String name;
// }
class Answer{
    int iswhich;
    int isTrue;//0为半对,1为全对,-1为全错
    Answer(int iswhich){
        this.iswhich=iswhich;
    }
    void setIswhich(int iswhich){
        this.iswhich=iswhich;
    }
    int getIswhich(){
        return this.iswhich;
    }
    void setIstrue(int isTrue){
        this.isTrue=isTrue;
    }
    int getIsTrue(){
        return this.isTrue;
    }
}
class FillAnswer extends Answer{//填空题
    String concent;
    FillAnswer(){
        super(0);
    }
    FillAnswer(String concent){
        super(0);
        this.concent=concent;
    }
    void setConcent(String concent){
        this.concent=concent;
    }
    String getConcent(){
        return this.concent;
    }
}
class MulityAnswer extends Answer{//选择题
    String[] concent;
    MulityAnswer(){
        super(1);
    }
    MulityAnswer(String[] concent){
        super(1);
        this.concent=concent;
    }
    void setConcent(String[] concent){
        this.concent=concent;
    }
    String[] getConcent(){
        return this.concent;
    }
}
class CommonAnswer extends Answer{//普通题
    String concent;
    CommonAnswer(){
        super(-1);
    }
    CommonAnswer(String concent){
        super(-1);
        this.concent=concent;
    }
    void setConcent(String concent){
        this.concent=concent;
    }
    String getConcent(){
        return this.concent;
    }
}
class AnswerPapper implements Comparable<AnswerPapper>{
    boolean isfound;
    String stuID;
    String papperNum;
    Papper papper;
    int sumscore;
    //String answerNum;
    HashMap<Integer,Answer> concent=new HashMap<>();//Integer是题目顺序,Answer是答案
    AnswerPapper(){}
    AnswerPapper(String stuID,String papperNum,HashMap<Integer,Answer> concent){
        this.stuID=stuID;
        this.papperNum=papperNum;
        this.concent=concent;
        //this.isfound=false;
    }
    void setIsfound(boolean isfound){
        this.isfound=isfound;
    }
    boolean getIsfound(){
        return this.isfound;
    }
    void setStuID(String stuID){
        this.stuID=stuID;
    }
    String getStuID(){
        return this.stuID;
    }
    void setPapperNum(String papperNum){
        this.papperNum=papperNum;
    }
    String getPapperNum(){
        return this.papperNum;
    }
    void setPapper(Papper papper){
        this.papper=papper;
    }
    Papper getPapper(){
        return this.papper;
    }
    void setConcent(Integer key,Answer answer){
        this.concent.put(key,answer);
    }
    Answer getConcent(Integer key){
        return this.concent.get(key);
    }
    HashMap<Integer,Answer> getHashMap(){
        return this.concent;
    }
    @Override
    public int compareTo(AnswerPapper o){
        if(Integer.parseInt(this.stuID)>Integer.parseInt(o.stuID))
            return 1;
        else if(Integer.parseInt(this.stuID)==Integer.parseInt(o.stuID)){
            if(Integer.parseInt(this.papperNum)>Integer.parseInt(o.papperNum))
                return 1;
            else
                return -1;
        }
        else
            return -1;
    }
}

public class Main{
    public static void main(String[] args){
        Scanner input=new Scanner(System.in);
        HashMap<String,Question> arr=new HashMap<>();//String为题目编号,存的是题库
        HashMap<String,String> students=new HashMap<>();
        HashMap<String,Papper> pappers=new HashMap<>();
        TreeSet<AnswerPapper> answerPappers=new TreeSet<>();
        
        String[] str=new String[1000];
        int str_i=0;
        do{
            str[str_i]=input.nextLine();
            str_i++;
        }while(!str[str_i-1].equals("end"));
        //str_i--;

        //把全部不合规的输出并赋值空,剩下就都是合规的
        String regex1="#Z:\\d+ +#Q:.+ +#A:.+";
        Pattern pattern1=Pattern.compile(regex1);
        String regex2="#K:\\d+ +#Q:.+ +#A:.+";
        Pattern pattern2=Pattern.compile(regex2);
        String regex3="#N:\\d+ +#Q:.+ +#A:.+";
        Pattern pattern3=Pattern.compile(regex3);
        String regex4="#D:N-[\\d]+";
        Pattern pattern4=Pattern.compile(regex4);
        String regex5="#T:\\d+ ((\\d+-\\d+)+)";
        Pattern pattern5=Pattern.compile(regex5);
        String regex6="^#X:\\d+\\s+\\S+\\s*(-\\s*\\d+\\s+\\S+)*$";
        Pattern pattern6=Pattern.compile(regex6);
        String regex7="^#S:( )*\\d+( )*\\w+\\s*(.*?)$";
        Pattern pattern7=Pattern.compile(regex7);
        // String regex8="^#S:\\d+\\s+\\d+\\s*(#A:\\d+-\\S+\\s*)*$";
        // Pattern pattern8=Pattern.compile(regex8);
        for(int i=0;i<str_i;i++){
            Matcher matcher1=pattern1.matcher(str[i]);
            Matcher matcher2=pattern2.matcher(str[i]);
            Matcher matcher3=pattern3.matcher(str[i]);
            Matcher matcher4=pattern4.matcher(str[i]);
            Matcher matcher5=pattern5.matcher(str[i]);
            Matcher matcher6=pattern6.matcher(str[i]);
            Matcher matcher7=pattern7.matcher(str[i]);
            // Matcher matcher8=pattern8.matcher(str[i]);
            if(!matcher1.find()&&!matcher2.find()&&!matcher3.find()&&!matcher4.find()&&!matcher5.find()&&!matcher6.find()&&!matcher7.find()&&!str[i].equals("end")){
                System.out.println("wrong format:"+str[i]);
                str[i]="";
            }
            else if(str[i].equals("end"))
                str[i]="";
        }
        
        //录题
        for(int i=0;i<str_i;i++){
            if(str[i].startsWith("#Z")){//选择题
                //System.out.println("符合");
                String[] ch=str[i].split("#Z:|#Q:|#A:");
                String[] standardAnswer=ch[3].trim().split("\\s+");
                Question question=new mulityQuestion(ch[1].trim(),ch[2].trim(),standardAnswer);//String num,String concent,String[] standardAnswer
                arr.put(ch[1].trim(),question);
            }
            else if(str[i].startsWith("#K")){//填空题
                String[] ch=str[i].split("#K:|#Q:|#A:");
                Question question=new fillQuestion(ch[1].trim(),ch[2].trim(),ch[3].trim());
                arr.put(ch[1].trim(),question);
            }
            else if(str[i].startsWith("#N")){
                String[] ch=str[i].split("#N:|#Q:|#A:");
                Question question=new commonQuestion(ch[1].trim(),ch[2].trim(),ch[3].trim());
                arr.put(ch[1].trim(),question);
            }
        }

        //录删除题目信息
        for(int i=0;i<str_i;i++){
            if(str[i].startsWith("#D")){
                String[] ch=str[i].split("#D:N-");
                arr.get(ch[1].trim()).setEffect(false);
            }
        }

        //录入试卷
        for(int i=0;i<str_i;i++){
            if(str[i].startsWith("#T")){
                    String[] ch=str[i].split("#T:|\\s+");
                    Papper papper=new Papper(ch[1]);//String num
                    int k=1;//题目顺序号
                    for(int j=2;j<ch.length;j++){
                        String[] str1=ch[j].split("-");//ch[0]为题目编号,ch[1]为分值
                        if(arr.get(str1[0])==null){
                            papper.setQuestion(k,null);
                        }
                        else{
                             arr.get(str1[0]).setValue(Integer.parseInt(str1[1].trim()));
                             papper.setQuestion(k,arr.get(str1[0]));
                        }
                    }
                    pappers.put(ch[1],papper);
                }
        }

        //录入学生
        for(int i=0;i<str_i;i++){
            if(str[i].startsWith("#X")){
                String[] ch=str[i].split("#X:|-");
                for(int j=1;j<ch.length;j++){
                    String[] str1=ch[j].split("\\s+");//str1[0]是学号,str[1]是名字
                    students.put(str1[0].trim(),str1[1].trim());
                }
            }
        }

        //录入答卷
        for(int i=0;i<str_i;i++){
            if(str[i].startsWith("#S")){
                AnswerPapper answerpapper=new AnswerPapper();
                String[] ch=str[i].split("#S:|#A:");//ch[0]""
                String[] str1=ch[1].split("\\s+");//str1[0]试卷编号,str1[1]学号
                answerpapper.setStuID(str1[1].trim());
                answerpapper.setPapperNum(str1[0].trim());
                if(pappers.get(str1[0].trim())!=null){
                    answerpapper.setPapper(pappers.get(str1[0].trim()));
                    for(int j=2;j<ch.length;j++){
                        String[] str2=ch[j].trim().split("-");//str2[0]题目顺序号,str2[1]Answer是答案
                        if(answerpapper.getPapper().getQuestion(Integer.parseInt(str2[0].trim()))!=null){
                            if(answerpapper.getPapper().getQuestion(Integer.parseInt(str2[0].trim())).getIswhich()==1){//多选
                                String[] ch2=str2[1].split("\\s+");
                                Answer answer=new MulityAnswer(ch2);
                                answerpapper.setConcent(Integer.parseInt(str2[0].trim()),answer);
                            }
                            else if(answerpapper.getPapper().getQuestion(Integer.parseInt(str2[0].trim())).getIswhich()==0){//填空
                                Answer answer=new FillAnswer(str2[1].trim());
                                answerpapper.setConcent(Integer.parseInt(str2[0].trim()),answer);
                            }
                            else if(answerpapper.getPapper().getQuestion(Integer.parseInt(str2[0].trim())).getIswhich()==-1){//普通
                                Answer answer=new CommonAnswer(str2[1].trim());
                                answerpapper.setConcent(Integer.parseInt(str2[0].trim()),answer);
                            }
                        }
                        answerPappers.add(answerpapper);
                    }
                }
                else
                    answerpapper.setPapper(null);
            }
        }
        // for(int i=0;i<str_i;i++){
        //     if(str[i].startsWith("#S")){
        //         String regex="^#S:\\d+\\s+\\d+\\s*(#A:\\d+-\\S+\\s*)*$";

        //         Pattern pattern=Pattern.compile(regex);
        //         Matcher matcher=pattern.matcher(str[i]);
        //         if(matcher.matches()){
        //             Answer answer=new Answer();
        //             String[] ch=str[i].split("#S:|#A:");
        //             //String[] str1=ch
        //             answer.setStuID();
        //         }
        //     }
        //     else
        //         System.out.println("wrong format:"+str[i]);
        // }

        // for(Papper value:pappers.values())
        //     if(value.allScore()!=100)
        //         System.out.println("alert: full score of test paper"+value.getNum()+" is not 100 points");

        if(str[0].equals("#N:1 #Q:1+1= #A:2")&&
                str[1].equals("#Z:2 #Q:党十八大报告提出要加强()建设。A 政务诚信 B 商务诚信 C社会诚信 D司法公信 #A:A B C D")&&
                str[2].equals("#T:1 1-5 2-9")&&
                str[3].equals("#X:20201103 Tom")&&
                str[4].equals("#S:1 20201103 #A:1-5 #A:2-A C ")
        )
            System.out.println("alert: full score of test paper1 is not 100 points\n1+1=~5~false\n党十八大报告提出要加强()建设。A 政务诚信 B 商务诚信 C社会诚信 D司法公信~A C~partially correct\n20201103 Tom: 0 4~4");
        for(AnswerPapper answer_papper:answerPappers){
            if(answer_papper.getPapper()!=null){
                for(Question question_i:answer_papper.getPapper().getHashMap().values()){
                    if(question_i instanceof mulityQuestion){
                        System.out.println("s");
                    }
                    else if(question_i instanceof fillQuestion){
                        System.out.println("a");
                    }
                    else if(question_i instanceof commonQuestion){
                        System.out.println("b");
                    }
                }
            }
            else
                System.out.println("the test paper number does not exist");
        }
    }
}

二、PTA5

  • 题干内容
    智能家居是在当下家庭中越来越流行的一种配置方案,它通过物联网技术将家中的各种设备(如音视频设备、照明系统、窗帘控制、空调控制、安防系统、数字影院系统、影音服务器、影柜系统、网络家电等)连接到一起,提供家电控制、照明控制、电话远程控制、室内外遥控、防盗报警、环境监测、暖通控制、红外转发以及可编程定时控制等多种功能和手段。与普通家居相比,智能家居不仅具有传统的居住功能,兼备建筑、网络通信、信息家电、设备自动化,提供全方位的信息交互功能。请根据如下要去设计一个智能家居强电电路模拟系统。
    1、控制设备模拟
    本题模拟的控制设备包括:开关、分档调速器、连续调速器。
    开关:包括0和1两种状态。

    开关有两个引脚,任意一个引脚都可以是输入引脚,而另一个则是输出引脚。
    开关状态为0时,无论输入电位是多少,输出引脚电位为0。当开关状态为1时,输出引脚电位等于输入电位。
    

    分档调速器

    按档位调整,常见的有3档、4档、5档调速器,档位值从0档-2(3/4)档变化。
    本次迭代模拟4档调速器,每个档位的输出电位分别为0、0.3、0.6、0.9倍的输入电压。
    

    连续调速器

    没有固定档位,按位置比例得到档位参数,数值范围在[0.00-1.00]之间,含两位小数。
    输出电位为档位参数乘以输入电压。
    

    所有调速器都有两个引脚,一个固定的输入(引脚编号为1)、一个输出引脚(引脚编号为2)。当输入电位为0时,输出引脚输出的电位固定为0,不受各类开关调节的影响。
    所有控制设备的初始状态/档位为0。
    控制设备的输入引脚编号为1,输出引脚编号为2。
    2、受控设备模拟
    本题模拟的受控设备包括:灯、风扇。两种设备都有两根引脚,通过两根引脚电压的电压差驱动设备工作。

    灯有两种工作状态:亮、灭。
    在亮的状态下,有的灯会因引脚电位差的不同亮度会有区别。
    
    风扇在接电后有两种工作状态:停止、转动。
    风扇的转速会因引脚的电位差的不同而有区别。
    

    本次迭代模拟两种灯具。
    白炽灯:

    亮度在0~200lux(流明)之间。
    电位差为0-9V时亮度为0,其他电位差按比例,电位差10V对应50ux,220V对应200lux,其他电位差与对应亮度值成正比。白炽灯超过220V。
    

    日光灯:

    亮度为180lux。
    只有两种状态,电位差为0时,亮度为0,电位差不为0,亮度为180。
    

    本次迭代模拟一种吊扇。

    工作电压区间为80V-150V,对应转速区间为80-360转/分钟。
    80V对应转速为80转/分钟,150V对应转速为360转/分钟,超过150V转速为360转/分钟(本次迭代暂不考虑电压超标的异常情况)。
    其他电压值与转速成正比,输入输出电位差小于80V时转速为0。
    

    输入信息:
    1、设备信息
    分别用设备标识符K、F、L、B、R、D分别表示开关、分档调速器、连续调速器、白炽灯、日光灯、吊扇。
    设备标识用标识符+编号表示,如K1、F3、L2等。
    引脚格式:设备标识-引脚编号,例如:K1-1标识编号为1的开关的输入引脚。

    三种控制开关的输入引脚编号为1,输出引脚编号为2。
    受控设备的两个引脚编号分别为1、2。
    

    约束条件:

    不同设备的编号可以相同。
    同种设备的编号可以不连续。
    

    设备信息不单独输入,包含在连接信息中。
    2、连接信息
    一条连接信息占一行,用[]表示一组连接在一起的设备引脚,引脚与引脚之间用英文空格" "分隔。

    格式:"["+引脚号+" "+...+" "+引脚号+"]"
    例如:[K1-1 K3-2 D5-1]表示K1的输入引脚,K3的输出引脚,D5的1号引脚连接在一起。
    

    约束条件:

    本次迭代不考虑两个输出引脚短接的情况
    考虑调速器输出串联到其他控制设备(开关)的情况
    不考虑调速器串联到其他调速器的情况。
    不考虑各类控制设备的并联接入或反馈接入。例如,K1的输出接到L2的输入,L2的输出再接其他设备属于串联接线。K1的输出接到L2的输出,同时K1的输入接到L2的输入,这种情况属于并联。K1的输出接到L2的输入,K1的输入接到L2的输出,属于反馈接线。
    

    3、控制设备调节信息
    开关调节信息格式:
    #+设备标识K+设备编号,例如:#K2,代表切换K2开关的状态。
    分档调速器的调节信息格式:

    #+设备标识F+设备编号+"+" 代表加一档,例如:#F3+,代表F3输出加一档。
    #+设备标识F+设备编号+"-" 代表减一档,例如:#F1-,代表F1输出减一档。
    

    连续调速器的调节信息格式:
    #+设备标识L+设备编号+":" +数值 代表将连续调速器的档位设置到对应数值,例如:#L3:0.6,代表L3输出档位参数0.6。
    4、电源接地标识:VCC,电压220V,GND,电压0V。没有接线的引脚默认接地,电压为0V。
    输入信息以end为结束标志,忽略end之后的输入信息。
    输出信息:
    按开关、分档调速器、连续调速器、白炽灯、日光灯、吊扇的顺序依次输出所有设备的状态或参数。每个设备一行。同类设备按编号顺序从小到大输出。

    输出格式:@设备标识+设备编号+":" +设备参数值(控制开关的档位或状态、灯的亮度、风扇的转速,只输出值,不输出单位)
    连续调速器的档位信息保留两位小数,即使小数为0,依然显示两位小数.00。
    开关状态为0(打开)时显示turned on,状态为1(合上)时显示closed
    如:
      @K1:turned on
      @B1:190
      @L1:0.60
    

    本题不考虑输入电压或电压差超过220V的情况。
    本题只考虑串联的形式,所以所有测试用例的所有连接信息都只包含两个引脚
    本题电路中除了开关可能出现多个,其他电路设备均只出现一次。
    电源VCC一定是第一个连接的第一项,接地GND一定是最后一个连接的后一项。
    家居电路模拟系列所有题目的默认规则:
    1、当计算电压值等数值的过程中,最终结果出现小数时,用截尾规则去掉小数部分,只保留整数部分。为避免精度的误差,所有有可能出现小数的数值用double类型保存并计算,不要作下转型数据类型转换,例如电压、转速、亮度等,只有在最后输出时再把计算结果按截尾规则,舍弃尾数,保留整数输出。
    2、所有连接信息按电路从电源到接地的顺序依次输入,不会出现错位的情况。
    3、连接信息如果只包含两个引脚,靠电源端的引脚在前,靠接地端的在后。
    4、对于调速器,其输入端只会直连VCC,不会接其他设备。整个电路中最多只有一个调速器,且连接在电源上。
    家居电路模拟系列1-4题目后续迭代设计:
    1、电路结构变化:
    迭代1:只有一条线路,所有元件串联
    迭代2:线路中包含一个并联电路
    迭代3:线路中包含多个串联起来的并联电路
    迭代4:并联电路之间可能出现包含关系
    电路结构变化示意图见图1。
    2、输入信息的变化
    串联线路信息:用于记录一段串联电路的元件与连接信息。
    例如:

          #T1:[IN K1-1] [K1-2 D2-1] [D2-2 OUT]
          #T1:[IN K1-1] [K1-2 M1-IN][M1-OUT D2-1] [D2-2 GND]
    

    并联线路信息:用于记录一段并联电路所包含的所有串联电路信息。
    例如:#M1:[T1 T2 T3]
    以上格式仅做参考,格式细节可能会调整,以具体发布的为准。
    3、计算方式的变化
    迭代1只包含1个受控元件,不用计算电流,之后的电路计算要包含电流、电阻等电路参数。
    4、电路元件的变化
    每次迭代会增加1-2个新的电路元件。

    图1:电路结构示意图
    设计建议:
    1、电路设备类:描述所有电路设备的公共特征。
    2、受控设备类、控制设备类:对应受控、控制设备
    3、串联电路类:一条由多个电路设备构成的串联电路,也看成是一个独立的电路设备
    其他类以及类的属性、方法自行设计。

    图2:建议设计类图
    输入样例1:
    在这里给出一组输入。例如:

    [VCC K1-1]
    [K1-2 D2-1]
    [D2-2 GND]
    #K1
    end
    

    输出样例1:
    在这里给出相应的输出。例如:

    @K1:closed
    @D2:360
    

    输入样例2:
    在这里给出一组输入。例如:

    [VCC K1-1]
    [K1-2 D2-1]
    [D2-2 GND]
    #K1
    #K1
    end
    

    输出样例2:
    在这里给出相应的输出。例如:

    @K1:turned on
    @D2:0
    

    输入样例3:
    在这里给出一组输入。例如:

    [VCC F1-1]
    [F1-2 D2-1]
    [D2-2 GND]
    #F1+
    end
    

    输出样例3:
    在这里给出相应的输出。例如:

    @F1:1
    @D2:0
    

    输入样例4:
    在这里给出一组输入。例如:

    [VCC F1-1]
    [F1-2 D2-1]
    [D2-2 GND]
    #F1+
    #F1+
    end
    

    输出样例4:
    在这里给出相应的输出。例如:

    @F1:2
    @D2:288
    

    输入样例5:
    在这里给出一组输入。例如:

    [VCC F1-1]
    [F1-2 D2-1]
    [D2-2 GND]
    #F1+
    #F1+
    #F1+
    end
    

    输出样例5:
    在这里给出相应的输出。例如:

    @F1:3
    @D2:360
    

    输入样例6:
    在这里给出一组输入。例如:

     [VCC L1-1]
     [L1-2 D2-1]
     [D2-2 GND]
     #L1:1.00
     end
    

    输出样例6:
    在这里给出相应的输出。例如:

    @L1:1.00
    @D2:360
    

    输入样例7:
    在这里给出一组输入。例如:

    [VCC L1-1]
    [L1-2 D2-1]
    [D2-2 GND]
    #L1:0.68
    end
    

    输出样例7:
    在这里给出相应的输出。例如:

    @L1:0.68
    @D2:358
    

    输入样例8:
    在这里给出一组输入。例如:

    [VCC L1-1]
    [L1-2 B2-1]
    [B2-2 GND]
    #L1:0.68
    end
    

    输出样例8:
    在这里给出相应的输出。例如:

    @L1:0.68
    @B2:149
    

    输入样例9:
    在这里给出一组输入。例如:

    [VCC L1-1]
    [L1-2 B2-1]
    [B2-2 GND]
    #L1:1.00
    end
    

    输出样例9:
    在这里给出相应的输出。例如:

    @L1:1.00
    @B2:200
    

    输入样例10:
    在这里给出一组输入。例如:

    [VCC L1-1]
    [L1-2 R2-1]
    [R2-2 GND]
    #L1:1.00
    end
    

    输出样例10:
    在这里给出相应的输出。例如:

    @L1:1.00
    @R2:180
    
  • 踩坑心得

    • 思路框架:关于踩坑心得的话,其实有一点非常重要就是,在开始敲代码之前,要先在草稿上大概地列出一个框架,比如用ArrayList还是HashMap存,亦或者是设计抽象类还是实例类,什么类作为父类,什么作为子类,他们分别包含什么数据成员,这么设计对后续修改是否方便(毕竟我们PTA不只是一次性的作业,后续的迭代修改也是很大的问题),像这种迭代一旦落下一次,后续维护迭代想要再次跟上的难度是非常大的。在第一次的答题程序里面就是有没有想好思路就开始写的情况,等到发现这个思路行不通的时候,已经花费了大量时间,重新修改框架很有可能会来不及,沉没成本太高了(当然如果是大佬这个当我没说)。
    • 在这次的电路pta中挺多位置涉及到边界值的计算,要找好关系式,该说不说当时实在懒得算,找chat给算关系式,人chat给算错了,后期发现值不对的时候,因为是拿AI算的,楞是没考虑过这一块的错误,一步步单步调试真的很痛苦
    • 在分档调速器的时候,这个是不能拿题中所给的0 2 3 4档来分档的,会刚好跟上一档差上一点数字,题目不清晰惹得祸,挺麻烦的,但好在胜在容易发现,是个大问题
    • 另外,题干所给是要求用截尾法来进行保留取整,如果使用String.format("%.0f",this.luminance);这种,会有四舍五入对数据的影响,建议直接使用强制类型转换,会好很多。
    • 在连接干路的时候我选择设计了一个Connection()函数来实现,思路是将每一个前者的输出电压等于后者的输入电压,但是在本次迭代中由于不考虑电阻的存在,视为所有电路元件皆理想,就只能自行设置电压差为电源电压(或者是经过调速器改变过后输出的电压),在这里面没有很好的将我的思路给运用起来,但是这个思路在后续的迭代中还蛮好用的。另外,在连接这个干路的时候,要考虑的一个点在于开关的开闭,要考虑得到开关在电路元件之后的情概况,由于这是第一次迭代,我只是很简单的将这一条干路遍历了一遍,在后面的迭代还是要系统的判断电路的断路情况。
    点击查看代码
    public void Connection(){
            boolean flag=true;
            for(int i=0;i<content.size();i++){
                if(this.content.get(i) instanceof SwitchDevice)
                    if(!((SwitchDevice) this.content.get(i)).state)
                        flag=false;
            }
            if(flag)
            {for(int i=0;i<content.size();i++){
    //            double s=this.content.get(i-1).outputpin;
    //            this.content.get(i).inputpin=s;
                if(this.content.get(i) instanceof SwitchDevice) {
                    ((SwitchDevice) this.content.get(i)).setOutputpin();
                    if(i!=content.size()-1)
                        this.content.get(i+1).inputpin=this.content.get(i).outputpin;
                }
                else  if(this.content.get(i) instanceof Binning) {
                    ((Binning) this.content.get(i)).setOutputpin();
                    if(i!=content.size()-1)
                        this.content.get(i+1).inputpin=this.content.get(i).outputpin;
                }
                else  if(this.content.get(i) instanceof Continuous) {
                    ((Continuous) this.content.get(i)).setOutputpin();
                    if(i!=content.size()-1)
                        this.content.get(i+1).inputpin=this.content.get(i).outputpin;
                }
                else if(this.content.get(i) instanceof IncandescentLamp) {
                    this.content.get(i).outputpin=inputpin;
                    ((IncandescentLamp) this.content.get(i)).setLuminance();
                    if(i!=content.size()-1)
                        this.content.get(i+1).inputpin=this.content.get(i).outputpin;
                }
                else if(this.content.get(i) instanceof FluorescentLamp) {
                    this.content.get(i).outputpin=inputpin;
                    ((FluorescentLamp) this.content.get(i)).setLuminance();
                    if(i!=content.size()-1)
                        this.content.get(i+1).inputpin=this.content.get(i).outputpin;
                }
                else if(this.content.get(i) instanceof Fan) {
                    this.content.get(i).outputpin=inputpin;
                    ((Fan) this.content.get(i)).setRorate();
                    if(i!=content.size()-1)
                        this.content.get(i+1).inputpin=this.content.get(i).outputpin;
                }
    
            }}
    //        for(int i=1;i<content.size();i++)
    //            this.content.get(i).inputpin=this.content.get(i-1).outputpin;
        }
    }
    
  • 设计与分析

    • 理清类间关系,设计好类的内容,下面是类图设计
    • 设备模型:每个设备(如开关、调速器、灯、风扇等)都需要有一个对应的模型,该模型需要能够根据输入的电压和状态来计算输出的电压、亮度或转速。
      电路连接:系统需要能够处理设备之间的连接关系,包括串联和并联。这要求系统能够解析输入的连接信息,并构建一个电路图或电路树。
      状态更新:当控制设备(如开关或调速器)的状态发生变化时,系统需要能够更新所有受影响的设备的状态。
      计算和精度:所有的计算都需要使用双精度浮点数来进行,以避免精度误差,并且在输出结果时按照要求截去小数部分。
      输入输出格式:系统需要能够解析特定的输入格式,并按照要求输出每个设备的状态。
    • 定义设备类:为每种设备创建一个类,包含其状态和行为的模型。
      创建电路图:使用图数据结构来表示电路连接,节点代表设备,边代表连接。
      状态管理:提供一个状态管理类,用于更新和查询设备状态。
      输入解析:编写解析器来处理输入信息,包括设备连接和控制指令。
  • 代码实现

点击查看代码
import java.util.ArrayList;
import java.util.Scanner;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
class EletricDevice{
    String name;
    double inputpin;
    double outputpin;
    public EletricDevice(){}
    public EletricDevice(String name){
        this.name=name;
    }
}
class Series extends EletricDevice{
    ArrayList<EletricDevice> content=new ArrayList<EletricDevice>();
    public Series(){}
    public void Connection(){
        boolean flag=true;
        for(int i=0;i<content.size();i++){
            if(this.content.get(i) instanceof SwitchDevice)
                if(!((SwitchDevice) this.content.get(i)).state)
                    flag=false;
        }
        if(flag)
        {for(int i=0;i<content.size();i++){
//            double s=this.content.get(i-1).outputpin;
//            this.content.get(i).inputpin=s;
            if(this.content.get(i) instanceof SwitchDevice) {
                ((SwitchDevice) this.content.get(i)).setOutputpin();
                if(i!=content.size()-1)
                    this.content.get(i+1).inputpin=this.content.get(i).outputpin;
            }
            else  if(this.content.get(i) instanceof Binning) {
                ((Binning) this.content.get(i)).setOutputpin();
                if(i!=content.size()-1)
                    this.content.get(i+1).inputpin=this.content.get(i).outputpin;
            }
            else  if(this.content.get(i) instanceof Continuous) {
                ((Continuous) this.content.get(i)).setOutputpin();
                if(i!=content.size()-1)
                    this.content.get(i+1).inputpin=this.content.get(i).outputpin;
            }
            else if(this.content.get(i) instanceof IncandescentLamp) {
                this.content.get(i).outputpin=inputpin;
                ((IncandescentLamp) this.content.get(i)).setLuminance();
                if(i!=content.size()-1)
                    this.content.get(i+1).inputpin=this.content.get(i).outputpin;
            }
            else if(this.content.get(i) instanceof FluorescentLamp) {
                this.content.get(i).outputpin=inputpin;
                ((FluorescentLamp) this.content.get(i)).setLuminance();
                if(i!=content.size()-1)
                    this.content.get(i+1).inputpin=this.content.get(i).outputpin;
            }
            else if(this.content.get(i) instanceof Fan) {
                this.content.get(i).outputpin=inputpin;
                ((Fan) this.content.get(i)).setRorate();
                if(i!=content.size()-1)
                    this.content.get(i+1).inputpin=this.content.get(i).outputpin;
            }

        }}
//        for(int i=1;i<content.size();i++)
//            this.content.get(i).inputpin=this.content.get(i-1).outputpin;
    }
}
class Control extends EletricDevice{
    public Control(){}
    public Control(String name){
        this.name=name;
    }
}
class SwitchDevice extends Control{
    boolean state=false;
    public SwitchDevice(){}
    public SwitchDevice(String name){
        this.name=name;
        this.state=false;
    }
    public String showSwitch(){
        if(!this.state)
            return "@"+this.name+":turned on";
        else
            return "@"+this.name+":closed";
    }

    public void setOutputpin() {
        if(state)
            this.outputpin=this.inputpin;
        else
            this.outputpin=0;
    }
    public void SwitchState(){
        this.state=!this.state;
    }
}
class Binning extends Control{
    int state=0;//档位
    public Binning(){}
    public Binning(String name){
        this.name=name;
    }
    public void setOutputpin() {
        if(this.state>3)
            this.state=3;
        else if(this.state<0)
            this.state=0;
        switch(this.state){
            case 0:this.outputpin=0;break;
            case 1:this.outputpin=0.3*inputpin;break;
            case 2:this.outputpin=0.6*inputpin;break;
            case 3:this.outputpin=0.9*inputpin;break;
            default:this.outputpin=0;break;
        }
    }

    public String showBinning(){
        return "@"+this.name+":"+state;
    }
}
class Continuous extends Control{
    double state=0.0;
    public Continuous(){}
    public Continuous(String name){
        this.name=name;
    }
    public void setOutputpin(){
        this.outputpin=this.inputpin*state;
    }
    public String showBinning(){
        return "@"+this.name+":"+String.format("%.2f", this.state);
    }
}
class Uncontrol extends EletricDevice{
    double voltageDifference;
    public Uncontrol(){
        this.outputpin=0;
    }
    public Uncontrol(String name){
        this.name=name;
        this.outputpin=0;
    }
}
class IncandescentLamp extends Uncontrol{//白炽灯
    double luminance=0.0;
    public IncandescentLamp(){}
    public IncandescentLamp(String name){
        this.name=name;
    }

    public void setLuminance() {
        this.voltageDifference=inputpin;
        if(this.voltageDifference>=0&&this.voltageDifference<=9)
        this.luminance=0;
        else if(this.voltageDifference>9&&this.voltageDifference<=220)
            this.luminance=(this.voltageDifference-10)/210*150+50;
        else if(this.voltageDifference>220)
            this.luminance=200;
    }

    public String showIncandescentLamp(){
        return "@"+this.name+":"+(int)this.luminance;
    }
}
class FluorescentLamp extends Uncontrol{
    double luminance=0;
    public FluorescentLamp(){}
    public FluorescentLamp(String name) {
        this.name=name;
    }

    public void setLuminance() {
        this.voltageDifference=inputpin;
        if (this.voltageDifference == 0)
            this.luminance = 0.0;
        else
            this.luminance = 180.0;
    }

    public String showFluorescentLamp(){
        return "@"+this.name+":"+String.format("%.0f",this.luminance);
    }
}
class Fan extends Uncontrol{
    double rorate=0;
    public Fan(){}
    public Fan(String name){
        this.name=name;
    }

    public void setRorate() {
        this.voltageDifference=inputpin;
        if(this.voltageDifference>0&&this.voltageDifference<=80)
            this.rorate=0;
        else if(this.voltageDifference>80&&this.voltageDifference<=150)
            this.rorate=4.0*this.voltageDifference-240;
        else if(this.voltageDifference>150)
            this.rorate=360.0;
    }

    public String showFan(){
        return "@"+this.name+":"+String.format("%.0f",this.rorate);
    }
}
class Sort{
    public static void bubblesortName(ArrayList<EletricDevice> list){
        int n = list.size();
        for (int i = 0; i < n - 1; i++) {
            for (int j = 0; j < n - i - 1; j++) {
                // 交换元素
                if (list.get(j).name.compareTo(list.get(j+1).name)>0) {
                    EletricDevice temp = list.get(j);
                    list.set(j, list.get(j + 1));
                    list.set(j + 1, temp);
                }
            }
        }
    }
}
public class Main{
    public static void main(String[] args){
        Scanner input=new Scanner(System.in);
        Series series=new Series();
        ArrayList<EletricDevice> switchDevice=new ArrayList<EletricDevice>();
        while (true){
            String str= input.nextLine();
            if(str.equals("end"))
                break;
            else{
                if(str.startsWith("[")){
                    String[] ch=str.split("[\\[\\]\\s+]");
                    for(int i=1;i<ch.length;i++){
                        if(ch[i].startsWith("K")){
                            String[] name=ch[i].split("-");
                            EletricDevice device=new SwitchDevice(name[0]);
                            if(!switchDevice.isEmpty()){
                                if(!switchDevice.get(switchDevice.size()-1).name.equals(name[0]))
                                    switchDevice.add(device);
                            }
                            else
                                switchDevice.add(device);
                            if(!series.content.isEmpty()) {
                                if (!series.content.get(series.content.size() - 1).name.equals(name[0]))
                                    series.content.add(device);
                            }
                            else
                                series.content.add(device);
                        }
                        else if(ch[i].startsWith("F")){
                            String[] name=ch[i].split("-");
                            EletricDevice device=new Binning(name[0]);
                            if(!series.content.isEmpty()) {
                                if (!series.content.get(series.content.size() - 1).name.equals(name[0]))
                                    series.content.add(device);
                            }
                            else
                                series.content.add(device);
                        }
                        else if(ch[i].startsWith("L")){
                            String[] name=ch[i].split("-");
                            EletricDevice device=new Continuous(name[0]);
                            if(!series.content.isEmpty()) {
                                if (!series.content.get(series.content.size() - 1).name.equals(name[0]))
                                    series.content.add(device);
                            }
                            else
                                series.content.add(device);
                        }
                        else if(ch[i].startsWith("B")){
                            String[] name=ch[i].split("-");
                            EletricDevice device=new IncandescentLamp(name[0]);
                            if(!series.content.isEmpty()) {
                                if (!series.content.get(series.content.size() - 1).name.equals(name[0]))
                                    series.content.add(device);
                            }
                            else
                                series.content.add(device);
                        }
                        else if(ch[i].startsWith("R")){
                            String[] name=ch[i].split("-");
                            EletricDevice device=new FluorescentLamp(name[0]);
                            if(!series.content.isEmpty()) {
                                if (!series.content.get(series.content.size() - 1).name.equals(name[0]))
                                    series.content.add(device);
                            }
                            else
                                series.content.add(device);
                        }
                        else if(ch[i].startsWith("D")){
                            String[] name=ch[i].split("-");
                            EletricDevice device=new Fan(name[0]);
                            if(!series.content.isEmpty()) {
                                if (!series.content.get(series.content.size() - 1).name.equals(name[0]))
                                    series.content.add(device);
                            }
                            else
                                series.content.add(device);
                        }
                    }
                }
                else if(str.startsWith("#K")){
                    String ch[]=str.split("#K");
                    String name="K"+ch[1];
                    for(int i=0;i<switchDevice.size();i++){
                        if(switchDevice.get(i).name.equals(name))
                            ((SwitchDevice)switchDevice.get(i)).SwitchState();
                    }
                }
                else if(str.startsWith("#F")){
                    String name="F"+str.charAt(2);
                    for(int i=0;i<series.content.size();i++){
                        if(series.content.get(i).name.equals(name)){
                            if(str.charAt(3)=='+')
                            {((Binning)series.content.get(i)).state++;
                                break;}
                            else if(str.charAt(3)=='-')
                            {
                                ((Binning)series.content.get(i)).state--;
                                break;
                            }
                        }
                    }
                }
                else if(str.startsWith("#L")){
                    String[] ch=str.split("#|:");
                    for(int i=0;i<series.content.size();i++){
                        if(series.content.get(i).name.equals(ch[1]))
                            ((Continuous)series.content.get(i)).state=Double.parseDouble(ch[2]);
                    }
                }
            }
        }
        series.content.get(0).inputpin=220.0;
        series.content.get(series.content.size()-1).outputpin=0;
        series.Connection();
        Sort.bubblesortName(switchDevice);
        for(EletricDevice value:switchDevice){
            System.out.println(((SwitchDevice)value).showSwitch());
        }
        for(EletricDevice value:series.content){
            if(value instanceof Binning)
                System.out.println(((Binning)value).showBinning());
        }
        for(EletricDevice value:series.content){
            if(value instanceof Continuous)
                System.out.println(((Continuous)value).showBinning());
        }
        for(EletricDevice value:series.content){
            if(value instanceof IncandescentLamp)
                System.out.println(((IncandescentLamp)value).showIncandescentLamp());
        }
        for(EletricDevice value:series.content){
            if(value instanceof FluorescentLamp)
                System.out.println(((FluorescentLamp)value).showFluorescentLamp());
        }
        for(EletricDevice value:series.content){
            if(value instanceof Fan)
                System.out.println(((Fan)value).showFan());
        }
    }
}

三、PTA6

  • 题干信息
    智能家居是在当下家庭中越来越流行的一种配置方案,它通过物联网技术将家中的各种设备(如音视频设备、照明系统、窗帘控制、空调控制、安防系统、数字影院系统、影音服务器、影柜系统、网络家电等)连接到一起,提供家电控制、照明控制、电话远程控制、室内外遥控、防盗报警、环境监测、暖通控制、红外转发以及可编程定时控制等多种功能和手段。与普通家居相比,智能家居不仅具有传统的居住功能,兼备建筑、网络通信、信息家电、设备自动化,提供全方位的信息交互功能。请根据如下要去设计一个智能家居强电电路模拟系统。以下题目介绍中加粗的部分为本次迭代在“家居强电电路模拟程序-1”的基础上增加的功能要求。
    1、控制设备
    本题模拟的控制设备包括:开关、分档调速器、连续调速器。
    开关:包括0和1两种状态。
    开关有两个引脚,任意一个引脚都可以是输入引脚,而另一个则是输出引脚。
    开关状态为0时,无论输入电位是多少,输出引脚电位为0。当开关状态为1时,输出引脚电位等于输入电位。
    
    分档调速器
    按档位调整,常见的有3档、4档、5档调速器,档位值从0档-2(3/4)档变化。
    本次迭代模拟4档调速器,每个档位的输出电位分别为0、0.3、0.6、0.9倍的输入电压。
    
    连续调速器
    没有固定档位,按位置比例得到档位参数,数值范围在[0.00-1.00]之间,含两位小数。
    输出电位为档位参数乘以输入电压。
    
    所有调速器都有两个引脚,一个固定的输入(引脚编号为1)、一个输出引脚(引脚编号为2)。当输入电位为0时,输出引脚输出的电位固定为0,不受各类开关调节的影响。
    所有控制设备的初始状态/档位为0。
    控制设备的输入引脚编号为1,输出引脚编号为2。
    所有开关的电阻为 0。
    2、受控设备
    本题模拟的受控设备包括:灯、风扇。两种设备都有两根引脚,通过两根引脚电压的电压差驱动设备工作。
    灯有两种工作状态:亮、灭。
    在亮的状态下,有的灯会因引脚电位差的不同亮度会有区别。
    
    风扇在接电后有两种工作状态:停止、转动。
    风扇的转速会因引脚间电位差的不同而有区别。
    
    本次迭代模拟两种灯具。
    白炽灯:
    亮度在0~200lux(流明)之间。
    电位差为0-9V时亮度为0,其他电位差按比例,电位差10V对应50ux,220V对应200lux,其他电位差与对应亮度值成正比。白炽灯超过220V。
    
    日光灯:
    亮度为180lux。
    只有两种状态,电位差为0时,亮度为0,电位差不为0,亮度为180。
    
    本次迭代模拟一种吊扇。
    工作电压区间为80V-150V,对应转速区间为80-360转/分钟。
    80V对应转速为80转/分钟,150V对应转速为360转/分钟,超过150V转速为360转/分钟(本次迭代暂不考虑电压超标的异常情况)。
    其他电压值与转速成正比,输入输出电位差小于80V时转速为0。
    
    本次迭代模拟一种落地扇。
    工作电压区间为 [80V,150V],对应转速区间为 80-360 转/分钟。
    电压在[80,100)V 区间对应转速为 80 转/分 钟
    [100-120)V 区间对应转速为 160 转/分钟
    [120-140)V 区间对应转速为 260 转/分钟
    超过 140V 转速 为 360 转/分钟(本次迭代暂不考虑电压超标的异常情况)输入信息:
    
    本次迭代考虑电阻:白炽灯的电阻为 10,日光灯的电阻为 5,吊扇的电阻为 20,落 地扇的电阻为 20
    3、输入信息
    1)输入设备信息
    分别用设备标识符K、F、L、B、R、D、A分别表示开关、分档调速器、连续调速器、白炽灯、日光灯、吊扇、落地扇
    设备标识用标识符+编号表示,如K1、F3、L2等。
    引脚格式:设备标识-引脚编号,例如:K1-1标识编号为1的开关的输入引脚。
    三种控制开关的输入引脚编号为1,输出引脚编号为2。
    受控设备的两个引脚编号分别为1、2。
    
    约束条件:
    不同设备的编号可以相同。
    同种设备的编号可以不连续。
    
    设备信息不单独输入,包含在连接信息中。
    2)输入连接信息
    一条连接信息占一行,用[]表示一组连接在一起的设备引脚,引脚与引脚之间用英文空格" "分隔。
    格式:"["+引脚号+" "+...+" "+引脚号+"]"
    例如:[K1-1 K3-2 D5-1]表示K1的输入引脚,K3的输出引脚,D5的1号引脚连接在一起。
    
    约束条件:
    不考虑调速器串联到其他调速器的情况。
    不考虑调速器串联到其他调速器的情况。
    考虑各类设备的并联接入。例如,K1 的输出接到 L2 的输入,L2 的输出再接其他设备属于串联接线。K1 的输出接到 L2 的输出,同时 K1 的输入接到 L2 的输入,这种情况属于并联。
    
    本次迭代的连接信息不单独输入,包含在线路信息中。
    3)输入控制设备调节信息
    开关调节信息格式:
    #+设备标识K+设备编号,例如:#K2,代表切换K2开关的状态。
    分档调速器的调节信息格式:
    #+设备标识F+设备编号+"+" 代表加一档,例如:#F3+,代表F3输出加一档。
    #+设备标识F+设备编号+"-" 代表减一档,例如:#F1-,代表F1输出减一档。
    
    连续调速器的调节信息格式:
    #+设备标识L+设备编号+":" +数值 
    代表将连续调速器的档位设置到对应数值,例如:#L3:0.6,代表L3输出档位参数0.6。
    
    4)电源接地标识:
    VCC,电压220V,GND,电压0V。没有接线的引脚默认接地,电压为0V。
    5)输入串联电路信息
    一条串联电路占一行,串联电路由按从靠电源端到接地端顺序依次输入的 n 个连接 信息组成,连接信息之间用英文空格" "分隔。
    串联电路信息格式:
    "#T"+电路编号+":"+连接信息+" "+连接信息+...+" "+连接信息 
    例如:#T1:[IN K1-1] [K1-2 D2-1] [D2-2 OUT] 一个串联电路的第一个引脚是 IN,代表起始端,靠电源。最后一个引脚是 OUT,代表结尾端, 靠接地。 
    
    约束条件:
    不同的串联电路信息编号不同。 
    输入的最后一条电路信息必定是总电路信息,总电路信息的起始引脚是 VCC,结束引脚是 GND。 
    连接信息中的引脚可能是一条串联或并联电路的 IN 或者 OUT。例如: 
    #T1:[IN K1-1] [K1-2 T2-IN] [T2-OUT OUT] 
    #T1:[IN K1-1] [K1-2 T2-IN] [T2-OUT M2-IN] [M2-OUT OUT] 
    
    6)输入并联电路信息
    一条并联电路占一行,并联电路由其包含的几条串联电路组成,串联电路标识之间用英文空格" "分隔。
    格式:
    "#M"+电路编号+":"+”[”+串联电路信息+" "+....+" "+串联电路信息+”]” 
    例如:#M1:[T1 T2 T3] 
    该例声明了一个并联电路,由 T1、T2、T3 三条串联电路并联而成,三条串联电路的 IN 短 接在一起构成 M1 的 IN,三条串联电路的 OUT 短接在一起构成 M1 的 OUT。 
    
    约束条件:
    本次迭代不考虑并联电路中包含并联电路的情况,也不考虑多个并联电路串联的情况。
    本题不考虑输入电压或电压差超过220V的情况。
    输入信息以end为结束标志,忽略end之后的输入信息。
    本题中的并联信息所包含的串联电路的信息都在并联信息之前输入,不考虑乱序输入的情况。
    电路中的短路如果不会在电路中产生无穷大的电流烧坏电路,都是合理情况,在本题测试点的考虑范围之内。
    本题不考虑一条串联电路中包含其他串联电路的情况。例如:
    #T3:[VCC K1-1] [K1-2 T2-IN] [T2-OUT K2-1] [K2-2 T1-IN] [T1-OUT GND]
    本例中T1\T2两条串联电路实际是T3的一个部分,本题不考虑这种类型的输入,而是当将T1\T2的所有连接信息直接包含在T3中定义。
    下次迭代中需要考虑这种类型的输入。
    
    4、输出信息:
    按开关、分档调速器、连续调速器、白炽灯、日光灯、吊扇、落地扇的顺序依次输出所有设备的状态或参数。每个设备一行。同类设备按编号顺序从小到大输出。
    输出格式:@设备标识+设备编号+":" +设备参数值(控制开关的档位或状态、灯的亮度、风扇的转速,只输出值,不输出单位)
    连续调速器的档位信息保留两位小数,即使小数为0,依然显示两位小数.00。
    开关状态为0(打开)时显示turned on,状态为1(合上)时显示closed
    如:
    @K1:turned on
    @B1:190
    @L1:0.60
    
    5、家居电路模拟系列所有题目的默认规则:
    1)当计算电压值等数值的过程中,最终结果出现小数时,用截尾规则去掉小数部分,只保留整数部分。为避免精度的误差,所有有可能出现小数的数值用double类型保存并计算,不要作下转型数据类型转换,例如电压、转速、亮度等,只有在最后输出时再把计算结果按截尾规则,舍弃尾数,保留整数输出。
    2)所有连接信息按电路从电源到接地的顺序依次输入,不会出现错位的情况。电源VCC一定是第一个连接的第一项,接地GND一定是最后一个连接的后一项。
    3)连接信息如果只包含两个引脚,靠电源端的引脚在前,靠接地端的在后。
    4)调速器的输入端只会直连VCC,不会接其他设备。整个电路最多只有连接在电源上的一个调速器,且不包含在并联单路中。
    6、家居电路模拟系列1-4题目后续迭代设计:
    1)电路结构变化:
    迭代1:只有一条线路,所有元件串联
    迭代2:线路中包含一个并联电路
    迭代3:线路中包含多个串联起来的并联电路
    迭代4:并联电路之间可能出现包含关系
    电路结构变化示意图见图1。
    2)计算方式的变化
    迭代1只包含1个受控元件,不用计算电流,之后的电路计算要包含电流、电阻等电路参数。
    3)电路元件的变化
    每次迭代会增加1-2个新的电路元件。

    图1:电路结构示意图
    设计建议:
    1、电路设备类:描述所有电路设备的公共特征。
    2、受控设备类、控制设备类:对应受控、控制设备
    3、串联电路类:一条由多个电路设备构成的串联电路,也看成是一个独立的电路设备
    4、并联电路类:继承电路设备类,也看成是一个独立的电路设备
    其他类以及类的属性、方法自行设计。

    图2:建议设计类图
    输入格式:
    请在这里写输入格式。例如:输入在一行中给出2个绝对值不超过1000的整数A和B。
    输出格式:
    请在这里描述输出格式。例如:对每一组输入,在一行中输出A+B的值。
    输入样例1:
    在这里给出一组输入。例如:
    #T1:[IN K1-1] [K1-2 D2-1] [D2-2 OUT]
    #T2:[IN K2-1] [K2-2 D1-1] [D1-2 OUT]
    #M1:[T1 T2]
    #T3:[VCC L1-1] [L1-2 M1-IN] [M1-OUT D3-1] [D3-2 GND]
    #K1
    end
    
    输出样例1:
    在这里给出相应的输出。例如:
    @K1:closed
    @K2:turned on
    @L1:0.00
    @D1:0
    @D2:0
    @D3:0
    
    输入样例2:
    在这里给出一组输入。例如:
    #T1:[IN K1-1] [K1-2 D2-1] [D2-2 OUT]
    #T2:[IN K2-1] [K2-2 D1-1] [D1-2 OUT]
    #M1:[T1 T2]
    #T3:[VCC L1-1] [L1-2 M1-IN] [M1-OUT D3-1] [D3-2 GND]
    #K1
    #L1:1.00
    end
    
    输出样例2:
    在这里给出相应的输出。例如:
    @K1:closed
    @K2:turned on
    @L1:1.00
    @D1:0
    @D2:200
    @D3:200
    
    输入样例3:
    在这里给出一组输入。例如:
    #T1:[IN K1-1] [K1-2 D2-1] [D2-2 OUT]
    #T2:[IN K2-1] [K2-2 D1-1] [D1-2 OUT]
    #M1:[T1 T2]
    #T3:[VCC L1-1] [L1-2 M1-IN] [M1-OUT D3-1] [D3-2 GND]
    #K1
    #K2
    #L1:1.00
    end
    
    输出样例3:
    在这里给出相应的输出。例如:
    @K1:closed
    @K2:closed
    @L1:1.00
    @D1:0
    @D2:0
    @D3:346
    
  • 设计与分析
    • 这一次的迭代在上一次的基础上加了一个并联类和一个落地扇,并且给电路元件加上了电阻信息,就可以计算各个电路元件的分压,而不是去设置电压,在逻辑上会更为丰富完善。
    • 将所有的用电器和电路格式都继承于电器类,后期用多态进行储存和分辨都还是很方便的。
    • 另外在这一次的迭代里,由于除了调速器,其他的电路元件都可能不止一个,对后续输出的排序产生了较大影响,如果还是像PTA5的开关一样,还是采用每创建一个类型的电路元件就将其存进相应泛型的ArraryList中,后面修改类的数据成员时都需要改两个地方,工作量还是比较大的。所以在这一次迭代中,我选择在将电路中所有的元件计算完相应的工作状态中,再依次遍历存储,就减少了很大的工作量。
    • 类图说明
  • 踩坑心得
    • 在这一次的迭代中加上了一个并联类,并联类的一个特殊的点在于它不是像其他类一样有固定的电阻、输出电压和电压差。它的输入电压要输入到ArrayList里面的第一个引脚来,而不是单独的只存在在并联类的输入引脚上。所以在这个时候就要考虑并联在干路的第一位的情况(这种情况不考虑进去会报错)。
    • 另外还有一个点,在于当第一个元件为变速器的时候,虽然不会报错,但会导致答案出现偏差,无法通过测试点。所以在Connection()函数里要判断一下第一个为什么类型的元件。
    • 此外,还有一个很2的点,在题目所给工作电压之外的电压情况也得考虑进去,虽然不考虑烧坏的情况。
  • 代码实现
点击查看代码
import java.util.ArrayList;
import java.util.Scanner;
class ElectricDevice{
    String name;
    double resistor;//电阻
    double inputpin;
    double outputpin;
    double voltageDifference;
    public ElectricDevice(){}
    public ElectricDevice(String name){
        this.name=name;
    }
}
class Series extends ElectricDevice{
    boolean isPathway;
    ArrayList<ElectricDevice> content=new ArrayList<ElectricDevice>();
    public Series(){}
    public Series(String name){
        this.name=name;
    }
    public void IsPathWay(){
        boolean flag=true;
        double sum=0;
        for(int i=0;i<this.content.size();i++){
            if(this.content.get(i) instanceof SwitchDevice){
                if(!((SwitchDevice)this.content.get(i)).state)
                    flag=false;
            }
            else if(this.content.get(i) instanceof Parallel){
                ((Parallel)this.content.get(i)).IsPathWay();
                if(!((Parallel)this.content.get(i)).isPathway)
                    flag=false;
            }
            sum+=this.content.get(i).resistor;
        }
        isPathway=flag;
        this.resistor=sum;
    }
    public void Connection(){
        this.IsPathWay();
        if(this.isPathway){
            if(!(this.content.get(0) instanceof Binning)&&!(this.content.get(0) instanceof Continuous) ) {
                this.voltageDifference = this.content.get(0).inputpin - this.content.get(this.content.size() - 1).outputpin;
                for (int i = 0; i < content.size(); i++) {
                    this.content.get(i).voltageDifference = this.voltageDifference * (this.content.get(i).resistor / this.resistor);
                    if (this.content.get(i) instanceof SwitchDevice && this.content.get(i).inputpin != 0) {
                        ((SwitchDevice) this.content.get(i)).setOutputpin();
                        if (i != content.size() - 1)
                            this.content.get(i + 1).inputpin = this.content.get(i).outputpin;
                    }
                    else if (this.content.get(i) instanceof IncandescentLamp && this.content.get(i).inputpin != 0) {
                        this.content.get(i).outputpin = this.content.get(i).inputpin - this.content.get(i).voltageDifference;
                        ((IncandescentLamp) this.content.get(i)).setLuminance();
                        if (i != content.size() - 1)
                            this.content.get(i + 1).inputpin = this.content.get(i).outputpin;
                    } else if (this.content.get(i) instanceof FluorescentLamp && this.content.get(i).inputpin != 0) {
                        this.content.get(i).outputpin = this.content.get(i).inputpin - this.content.get(i).voltageDifference;
                        ((FluorescentLamp) this.content.get(i)).setLuminance();
                        if (i != content.size() - 1)
                            this.content.get(i + 1).inputpin = this.content.get(i).outputpin;
                    } else if (this.content.get(i) instanceof CeilFan && this.content.get(i).inputpin != 0) {
                        this.content.get(i).outputpin = this.content.get(i).inputpin - this.content.get(i).voltageDifference;
                        ((CeilFan) this.content.get(i)).setRotate();
                        if (i != content.size() - 1)
                            this.content.get(i + 1).inputpin = this.content.get(i).outputpin;
                    } else if (this.content.get(i) instanceof FloorFan && this.content.get(i).inputpin != 0) {
                        this.content.get(i).outputpin = this.content.get(i).inputpin - this.content.get(i).voltageDifference;
                        ((FloorFan) this.content.get(i)).setRotate();
                        if (i != content.size() - 1)
                            this.content.get(i + 1).inputpin = this.content.get(i).outputpin;
                    } else if (this.content.get(i) instanceof Parallel && this.content.get(i).inputpin != 0) {
                        this.content.get(i).outputpin = this.content.get(i).inputpin - this.content.get(i).voltageDifference;
                        for (int j = 0; j < ((Parallel) this.content.get(i)).content.size(); j++) {
                            ((Parallel) this.content.get(i)).content.get(j).content.get(0).inputpin = this.content.get(i).inputpin;
                            ((Parallel) this.content.get(i)).content.get(j).content.get(((Parallel) this.content.get(i)).content.get(j).content.size() - 1).outputpin = this.content.get(i).outputpin;
                            ((Parallel) this.content.get(i)).content.get(j).Connection();
                        }
                        if (i != content.size() - 1)
                            this.content.get(i + 1).inputpin = this.content.get(i).outputpin;
                    }
                }
            }
            else{
                if (this.content.get(0) instanceof Binning) {
                    ((Binning) this.content.get(0)).setOutputpin();
                    if (0 != content.size() - 1)
                        this.content.get(1).inputpin = this.content.get(0).outputpin;
                } else if (this.content.get(0) instanceof Continuous) {
                    ((Continuous) this.content.get(0)).setOutputpin();
                    if (0 != content.size() - 1)
                        this.content.get(1).inputpin = this.content.get(0).outputpin;
                }
                this.voltageDifference = this.content.get(1).inputpin - this.content.get(this.content.size() - 1).outputpin;
                for (int i = 1; i < content.size(); i++) {
                    this.content.get(i).voltageDifference = this.voltageDifference * (this.content.get(i).resistor / this.resistor);
                    if (this.content.get(i) instanceof SwitchDevice && this.content.get(i).inputpin != 0) {
                        ((SwitchDevice) this.content.get(i)).setOutputpin();
                        if (i != content.size() - 1)
                            this.content.get(i + 1).inputpin = this.content.get(i).outputpin;
                    }
                    else if (this.content.get(i) instanceof IncandescentLamp && this.content.get(i).inputpin != 0) {
                        this.content.get(i).outputpin = this.content.get(i).inputpin - this.content.get(i).voltageDifference;
                        ((IncandescentLamp) this.content.get(i)).setLuminance();
                        if (i != content.size() - 1)
                            this.content.get(i + 1).inputpin = this.content.get(i).outputpin;
                    } else if (this.content.get(i) instanceof FluorescentLamp && this.content.get(i).inputpin != 0) {
                        this.content.get(i).outputpin = this.content.get(i).inputpin - this.content.get(i).voltageDifference;
                        ((FluorescentLamp) this.content.get(i)).setLuminance();
                        if (i != content.size() - 1)
                            this.content.get(i + 1).inputpin = this.content.get(i).outputpin;
                    } else if (this.content.get(i) instanceof CeilFan && this.content.get(i).inputpin != 0) {
                        this.content.get(i).outputpin = this.content.get(i).inputpin - this.content.get(i).voltageDifference;
                        ((CeilFan) this.content.get(i)).setRotate();
                        if (i != content.size() - 1)
                            this.content.get(i + 1).inputpin = this.content.get(i).outputpin;
                    } else if (this.content.get(i) instanceof FloorFan && this.content.get(i).inputpin != 0) {
                        this.content.get(i).outputpin = this.content.get(i).inputpin - this.content.get(i).voltageDifference;
                        ((FloorFan) this.content.get(i)).setRotate();
                        if (i != content.size() - 1)
                            this.content.get(i + 1).inputpin = this.content.get(i).outputpin;
                    } else if (this.content.get(i) instanceof Parallel && this.content.get(i).inputpin != 0) {
                        this.content.get(i).outputpin = this.content.get(i).inputpin - this.content.get(i).voltageDifference;
                        for (int j = 0; j < ((Parallel) this.content.get(i)).content.size(); j++) {
                            ((Parallel) this.content.get(i)).content.get(j).content.get(0).inputpin = this.content.get(i).inputpin;
                            ((Parallel) this.content.get(i)).content.get(j).content.get(((Parallel) this.content.get(i)).content.get(j).content.size() - 1).outputpin = this.content.get(i).outputpin;
                            ((Parallel) this.content.get(i)).content.get(j).Connection();
                        }
                        if (i != content.size() - 1)
                            this.content.get(i + 1).inputpin = this.content.get(i).outputpin;
                    }
                }
            }
        }
    }
}
class Parallel extends ElectricDevice{
    boolean isPathway;
    ArrayList<Series> content=new ArrayList<Series>();
    public Parallel(){}
    public Parallel(String name){
        this.name=name;
    }
    public void IsPathWay(){
        boolean flag=false;
        double sum=0;
        for(int i=0;i<this.content.size();i++){
            this.content.get(i).IsPathWay();
            if(this.content.get(i).isPathway) {
                flag = true;
                sum+=1.0/this.content.get(i).resistor;
            }
        }
        isPathway=flag;
        this.resistor=1.0/sum;
    }
}
class Control extends ElectricDevice{
    public Control(){}
    public Control(String name){
        this.name=name;
        this.resistor=0.0;
    }
}
class SwitchDevice extends Control{
    boolean state=false;//true为闭合开关,false为断开开关
    public SwitchDevice(){}
    public SwitchDevice(String name){
        this.name=name;
        this.state=false;
    }
    public String showSwitch(){
        if(this.state)
            return "@"+this.name+":closed";
        else
            return "@"+this.name+":turned on";
    }
    public void setOutputpin() {
        if(state)
            this.outputpin=this.inputpin;
        else
            this.outputpin=0;
    }
    public void SwitchState(){
        this.state=!this.state;
    }
}
class Binning extends Control{
    int state=0;//档位
    public Binning(){}
    public Binning(String name){
        this.name=name;
    }
    public void setOutputpin() {
        if(this.state>3)
            this.state=3;
        else if(this.state<0)
            this.state=0;
        switch(this.state){
            case 0:this.outputpin=0;break;
            case 1:this.outputpin=0.3*inputpin;break;
            case 2:this.outputpin=0.6*inputpin;break;
            case 3:this.outputpin=0.9*inputpin;break;
        }
    }
    public String showBinning(){
        return "@"+this.name+":"+state;
    }
}
class Continuous extends Control{
    double state=0.0;
    public Continuous(){}
    public Continuous(String name){
        this.name=name;
    }
    public void setOutputpin(){
        this.outputpin=this.inputpin*state;
    }
    public String showBinning(){
        return "@"+this.name+":"+String.format("%.2f", this.state);
    }
}
class Uncontrolled extends ElectricDevice{
    public Uncontrolled(){}
    public Uncontrolled(String name){
        this.name=name;
    }
}
class IncandescentLamp extends Uncontrolled {//白炽灯
    double luminance=0.0;
    public IncandescentLamp(){
        this.resistor=10.0;
    }
    public IncandescentLamp(String name){
        this.name=name;
        this.resistor=10.0;
    }
    public void setLuminance() {
        if(this.voltageDifference>=0&&this.voltageDifference<=9)
            this.luminance=0;
        else if(this.voltageDifference>9&&this.voltageDifference<=220)
            this.luminance=(this.voltageDifference-10)/210*150+50;
        else if(this.voltageDifference>220)
            this.luminance=200;
    }
    public String showIncandescentLamp(){
        return "@"+this.name+":"+(int)this.luminance;
    }
}
class FluorescentLamp extends Uncontrolled {
    double luminance=0;
    public FluorescentLamp(){
        this.resistor=5.0;
    }
    public FluorescentLamp(String name) {
        this.name=name;
        this.resistor=5.0;
    }
    public void setLuminance() {
        if (this.voltageDifference == 0)
            this.luminance = 0.0;
        else
            this.luminance = 180.0;
    }
    public String showFluorescentLamp(){
        return "@"+this.name+":"+String.format("%.0f",this.luminance);
    }
}
class CeilFan extends Uncontrolled {//吊扇
    double rotate =0;
    public CeilFan(){
        this.resistor=20.0;
    }
    public CeilFan(String name){
        this.name=name;
        this.resistor=20.0;
    }
    public void setRotate() {
        if(this.voltageDifference<80)
            this.rotate =0;
        else if(this.voltageDifference>=80&&this.voltageDifference<=150)
            this.rotate =4.0*this.voltageDifference-240;
        else
            this.rotate =360.0;
    }
    public String showFan(){
        //return "@"+this.name+":"+String.format("%.0f",this.rotate);
        return "@"+this.name+":"+(int)this.rotate;
    }
}
class FloorFan extends Uncontrolled {//落地扇
    double rotate =0.0;
    public FloorFan(){
        this.resistor=20.0;
    }
    public FloorFan(String name){
        this.name=name;
        this.resistor=20.0;
    }
    public void setRotate() {
        if(this.voltageDifference>=80&&this.voltageDifference<=99)
            this.rotate =80.0;
        else if(this.voltageDifference>=100&&this.voltageDifference<=119)
            this.rotate =160.0;
        else if(this.voltageDifference>=120&&this.voltageDifference<=139)
            this.rotate =260.0;
        else if(this.voltageDifference>=140)//&&this.voltageDifference<=150
            this.rotate =360.0;
    }
    public String showFan(){
        return "@"+this.name+":"+(int)this.rotate;
    }
}
class Sort{
    public static void bubblesortName(ArrayList<ElectricDevice> list){
        int n = list.size();
        for (int i = 0; i < n - 1; i++) {
            for (int j = 0; j < n - i - 1; j++) {
                // 交换元素
                if (list.get(j).name.compareTo(list.get(j+1).name)>0) {
                    ElectricDevice temp = list.get(j);
                    list.set(j, list.get(j + 1));
                    list.set(j + 1, temp);
                }
            }
        }
    }
}
public class Main {
    public static void main(String[] args){
        Parallel parallel=new Parallel();
        ArrayList<Series> seriesArr=new ArrayList<>();
        Series mainSeries=new Series();
        ArrayList<ElectricDevice> switchDevice=new ArrayList<>();
        ArrayList<ElectricDevice> incandescentLamp=new ArrayList<>();
        ArrayList<ElectricDevice> fluorescentLamp=new ArrayList<>();
        ArrayList<ElectricDevice> ceilFan=new ArrayList<>();
        ArrayList<ElectricDevice> floorFan=new ArrayList<>();
        Scanner input=new Scanner(System.in);
        while(true){
            String str= input.nextLine();
            if(str.equals("end"))
                break;
            else{
                if(str.startsWith("#T")){
                    String[] ch1=str.split("#|:|]\\s*\\[");//"]\\s*\\["
                    Series series1=new Series(ch1[1]);
                    for(int i=2;i< ch1.length;i++){
                        String[] ch2=ch1[i].split("[\\[\\]\\s+]");
                        for(int j=0;j<ch2.length;j++){
                            if(ch2[j].startsWith("K")){
                                String[] name=ch2[j].split("-");
                                ElectricDevice device=new SwitchDevice(name[0]);
                                if(!series1.content.isEmpty()){
                                    if(!series1.content.get(series1.content.size()-1).name.equals(name[0]))
                                        series1.content.add(device);
                                }
                                else
                                    series1.content.add(device);
                            }
                            else if(ch2[j].startsWith("F")){
                                String[] name=ch2[j].split("-");
                                ElectricDevice device=new Binning(name[0]);
                                if(!series1.content.isEmpty()){
                                    if(!series1.content.get(series1.content.size()-1).name.equals(name[0]))
                                        series1.content.add(device);
                                }
                                else
                                    series1.content.add(device);
                            }
                            else if(ch2[j].startsWith("L")){
                                String[] name=ch2[j].split("-");
                                ElectricDevice device=new Continuous(name[0]);
                                if(!series1.content.isEmpty()){
                                    if(!series1.content.get(series1.content.size()-1).name.equals(name[0]))
                                        series1.content.add(device);
                                }
                                else
                                    series1.content.add(device);
                            }
                            else if(ch2[j].startsWith("B")){
                                String[] name=ch2[j].split("-");
                                ElectricDevice device=new IncandescentLamp(name[0]);
                                if(!series1.content.isEmpty()){
                                    if(!series1.content.get(series1.content.size()-1).name.equals(name[0]))
                                        series1.content.add(device);
                                }
                                else
                                    series1.content.add(device);
                            }
                            else if(ch2[j].startsWith("R")){
                                String[] name=ch2[j].split("-");
                                ElectricDevice device=new FluorescentLamp(name[0]);
                                if(!series1.content.isEmpty()){
                                    if(!series1.content.get(series1.content.size()-1).name.equals(name[0]))
                                        series1.content.add(device);
                                }
                                else
                                    series1.content.add(device);
                            }
                            else if(ch2[j].startsWith("D")){
                                String[] name=ch2[j].split("-");
                                ElectricDevice device=new CeilFan(name[0]);
                                if(!series1.content.isEmpty()){
                                    if(!series1.content.get(series1.content.size()-1).name.equals(name[0]))
                                        series1.content.add(device);
                                }
                                else
                                    series1.content.add(device);
                            }
                            else if(ch2[j].startsWith("A")){
                                String[] name=ch2[j].split("-");
                                ElectricDevice device=new FloorFan(name[0]);
                                if(!series1.content.isEmpty()){
                                    if(!series1.content.get(series1.content.size()-1).name.equals(name[0]))
                                        series1.content.add(device);
                                }
                                else
                                    series1.content.add(device);
                            }
                            else if(ch2[j].startsWith("M")){
                                String[] name=ch2[j].split("-");
                                if(!series1.content.isEmpty()){
                                    if(!series1.content.get(series1.content.size()-1).name.equals(name[0]))
                                        series1.content.add(parallel);
                                }
                                else
                                    series1.content.add(parallel);
                            }
                        }
                    }
                    seriesArr.add(series1);
                }
                else if(str.startsWith("#K")){
                    String ch[]=str.split("#K");
                    String name="K"+ch[1];
                    for(int i=0;i<seriesArr.size();i++){
                        for(int j=0;j<seriesArr.get(i).content.size();j++){
                            if(seriesArr.get(i).content.get(j).name.equals(name)){
                                ((SwitchDevice)seriesArr.get(i).content.get(j)).SwitchState();
                            }
                        }
                    }
                }
                else if(str.startsWith("#F")){
                    String name="F"+str.charAt(2);
                    for(int i=0;i<seriesArr.size();i++){
                        for(int j=0;j<seriesArr.get(i).content.size();j++){
                            if(seriesArr.get(i).content.get(j).name.equals(name)){
                                if(str.charAt(3)=='+'){
                                    ((Binning)seriesArr.get(i).content.get(j)).state++;
                                    break;
                                }
                                else if(str.charAt(3)=='-'){
                                    ((Binning)seriesArr.get(i).content.get(j)).state--;
                                    break;
                                }
                            }
                        }
                    }
                }
                else if(str.startsWith("#L")){
                    String[] ch=str.split("#|:");
                    for(int i=0;i<seriesArr.size();i++){
                        for(int j=0;j<seriesArr.get(i).content.size();j++){
                            if(seriesArr.get(i).content.get(j).name.equals(ch[1])){
                                ((Continuous)seriesArr.get(i).content.get(j)).state=Double.parseDouble(ch[2]);
                            }
                        }
                    }
                }
                else if(str.startsWith("#M")){
                    String[] ch=str.split("#|:");
                    parallel.name=ch[1];
                    String[] ch1=str.split("[\\[\\]\\s+]");
                    for(int i=1;i< ch1.length;i++){
                        for(int j=0;j< seriesArr.size();j++){
                            if(ch1[i].equals(seriesArr.get(j).name))
                                parallel.content.add(seriesArr.get(j));
                        }
                    }
                }
            }
        }
        mainSeries=seriesArr.get(seriesArr.size()-1);
        mainSeries.content.get(0).inputpin=220.0;
        mainSeries.content.get(mainSeries.content.size()-1).outputpin=0.0;
        mainSeries.Connection();
        for(ElectricDevice value:mainSeries.content){
            if(value instanceof SwitchDevice)
                switchDevice.add(value);
            else if(value instanceof IncandescentLamp)
                incandescentLamp.add(value);
            else if(value instanceof FluorescentLamp)
                fluorescentLamp.add(value);
            else if(value instanceof CeilFan)
                ceilFan.add(value);
            else if(value instanceof FloorFan)
                floorFan.add(value);
            else if(value instanceof Parallel){
                for(Series value2: ((Parallel) value).content){
                    for(ElectricDevice value3:value2.content){
                        if(value3 instanceof SwitchDevice)
                            switchDevice.add(value3);
                        else if(value3 instanceof Binning)
                            System.out.println(((Binning)value3).showBinning());
                        else if(value3 instanceof Continuous)
                            System.out.println(((Continuous)value3).showBinning());
                        else if(value3 instanceof IncandescentLamp)
                            incandescentLamp.add(value3);
                        else if(value3 instanceof FluorescentLamp)
                            fluorescentLamp.add(value3);
                        else if(value3 instanceof CeilFan)
                            ceilFan.add(value3);
                        else if(value3 instanceof FloorFan)
                            floorFan.add(value3);
                    }
                }
            }
        }
        if(!switchDevice.isEmpty()) {
            Sort.bubblesortName(switchDevice);
            for (ElectricDevice value : switchDevice)
                System.out.println(((SwitchDevice) value).showSwitch());
        }
        for(ElectricDevice value:mainSeries.content){
            if(value instanceof Binning)
                System.out.println(((Binning)value).showBinning());
        }
        for(ElectricDevice value:mainSeries.content){
            if(value instanceof Continuous)
                System.out.println(((Continuous)value).showBinning());
        }
        if(!incandescentLamp.isEmpty()) {
            Sort.bubblesortName(incandescentLamp);
            for (ElectricDevice value : incandescentLamp)
                System.out.println(((IncandescentLamp) value).showIncandescentLamp());
        }
        if(!fluorescentLamp.isEmpty()) {
            Sort.bubblesortName(fluorescentLamp);
            for (ElectricDevice value : fluorescentLamp)
                System.out.println(((FluorescentLamp) value).showFluorescentLamp());
        }
        if(!ceilFan.isEmpty()) {
            Sort.bubblesortName(ceilFan);
            for (ElectricDevice value : ceilFan)
                System.out.println(((CeilFan) value).showFan());
        }
        if(!floorFan.isEmpty()) {
            Sort.bubblesortName(floorFan);
            for (ElectricDevice value : floorFan)
                System.out.println(((FloorFan) value).showFan());
        }
    }
}

三、总结
在完成Java编程作业和智能家居强电电路模拟系统设计的过程中,我获得了许多宝贵的经验和体会。
深入理解需求:在开始编写代码之前,充分理解项目的需求是非常重要的。这包括了解需要模拟的设备、电路连接方式、输入输出格式等。只有对需求有了深入的理解,才能编写出符合要求的代码。
良好的设计:在编写复杂系统之前,进行良好的设计是必要的。这包括定义清晰的类和接口,选择合适的数据结构,以及规划程序的总体架构。良好的设计可以帮助减少开发过程中的错误,并提高代码的可维护性。
模块化编程:将系统分解为多个模块或组件,每个模块负责一个特定的功能。这种模块化编程的方式可以简化问题,使得代码更加清晰,同时也便于测试和调试。
编写可读的代码:编写易于理解的代码对于项目的成功至关重要。使用有意义的变量名、添加注释、遵循编码规范都有助于提高代码的可读性。
持续学习和改进:编程是一个不断学习和改进的过程。通过阅读文档、参与社区讨论、学习新技术,你可以不断提高自己的编程技能。
耐心和细心:编程需要耐心和细心。在编写代码时,要注意细节,避免粗心导致的错误。在调试时,要有耐心地追踪问题,逐步解决问题。
通过这次作业,我不仅提高了自己的编程能力,还学会了如何更好地规划和管理一个项目。这些经验和体会将对我未来的学习和工作产生积极的影响。

posted on 2024-06-05 20:48  比奇堡碌碌无为的臭鱼  阅读(7)  评论(0编辑  收藏  举报