PTA 软件设计与体系结构 7-2

7-2 sda-2.2 设计模式-Composite-Visitor

已知年级由班级组成、班级由学生组成,在成绩发布之后每个学生会根据自身成绩的情况做出不同的响应,请基于组合(Composite)模式与访问者(Visitor)模式设计该程序。

主程序关键代码:

public class Main {
    
    public static void main(String[] args) {
        
        /* 
         * 输入代码,请保留  
         * 数组inputs对应控制台输入
         * inputs[0]: 0 - 年级、班级、学生等数据在程序内由createObjectStructure方法创建;
         *            1 - 年级、班级、学生等数据从控制台输入并经过parseInputs方法分析得到;
         * inputs[1]: {g01:{c01:{s01-Jack-80,s02-Tom-70},c02:{s03-Green-90,s04-Smith-70}},g02:{c03:{s05-Jones-75,s06-Jerry-85}}}
         *  */
        
        Scanner sc = new Scanner(System.in);
        String[] inputs = new String[2];
        for(int i=0;i<inputs.length;i++){
            inputs[i]=sc.nextLine();
        }
        sc.close();
        
         visitor = new ...();  //创建访问者
        ...[] grades=null;
        
        // 根据输入情况来选择采用何种方式创建年级、班级、学生等对象,并将其组合。
        if (Integer.parseInt(inputs[0])==0) 
            grades = createObjectStructure();
        else
            grades = parseInputs(inputs[1]);    
        
        ....accept(visitor);  //接受访问者对象,输出结果
        ...
    }
    
    /* 创建年级、班级、学生对象并将其组合起来 */
    public static Grade[] createObjectStructure() {
        /*  创建的年级、班级、学生对象如下:
        
        年级:g01,该年级有以下班级:
                班级:c101,该班级有以下学生
                        学生:s01,Jack,70
        ----s04,Green,50
        --c102
        ----s02,Tom,80
        ----s05,Smith,60
        g02
        --c103
        ----s03,Jerry,90
        ----s06,Jones,70    
        */
        ...
    }    
    
    /* 通过分析strInput字符串创建年级、班级、学生对象并将其组合起来 */
    public static Grade[] parseInputs(String strInput) {
        ...
    }    

}

输入格式:

第1行:创建对象的方式,0或1,含义参见主程序关键代码注释
第2行:年级、班级、学生数据,格式为

{年级1:{班级1:{学号1-姓名1-成绩1,...},...},...}  

参见输入输出样例

输出格式:

年级  
--班级(人数)  
----学号1,姓名1,成绩1,passed
----学号2,姓名2,成绩2,failed

passed表示通过考试,即分数大于或等于60分
failed表示未通过考试,即分数小于60分

输入样例:

当第一行输入为0时,第二行可以输入任意内容,对结果无影响

0
123

当第一行输入为1时,第二行应按指定格式输入年级、班级、学生等实体内容

1
{g01:{c01:{s01-Jack-80,s02-Tom-70},c02:{s03-Green-90,s04-Smith-70}},g02:{c03:{s05-Jones-75,s06-Jerry-85}}}

输出样例:

当第一行输入为0时,输出内容确定,必定为以下内容:

g01
--c101(2)
----s01,Jack,70,passed
----s04,Green,50,failed
--c102(2)
----s02,Tom,80,passed
----s05,Smith,60,passed
g02
--c103(2)
----s03,Jerry,90,passed
----s06,Jones,70,passed

当第一行输入为1时,输出内容由第二行输入数据决定

g01
--c01(2)
----s01,Jack,80,passed
----s02,Tom,70,passed
--c02(2)
----s03,Green,90,passed
----s04,Smith,70,passed
g02
--c03(2)
----s05,Jones,75,passed
----s06,Jerry,85,passed

用栈优雅完成,测试点全过

import java.util.*;
interface Element {
    void accept(Visitor visitor);
    String getType();
    String getId();
    void setId(String id);
    String getIn();
}
interface Visitor {
    void visit(Grade grade);
    void visit(Clazz clazz);
    void visit(Student student);
}
class Clazz implements Element{
    private String id;
    private String in;
    private final List<Student> studentList = new ArrayList<>();

    public Clazz(String id) {
        this.in = id;
        this.id = id.replaceAll("\\{","").replaceAll("\\}","");
    }

    @Override
    public String getId() {
        return id;
    }

    @Override
    public void setId(String id) {
        this.id = id;
    }

    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
        Collections.reverse(studentList);
        studentList.forEach(student -> {
            student.accept(visitor);
        });
    }

    @Override
    public String getType() {
        return "c";
    }

    public Clazz add(Element element) {
        studentList.add((Student) element);
        return this;
    }

    public Clazz remove(Element element) {
        studentList.remove((Student) element);
        return this;
    }

    public List<Student> getStudentList() {
        return studentList;
    }

    @Override
    public String getIn() {
        return in;
    }
}
class Grade implements Element{
    private String id;
    private String in;
    private final List<Clazz> clazzList = new ArrayList<>();

    public Grade(String id) {
        this.in = id;
        this.id = id.replaceAll("\\{","").replaceAll("\\}","");
    }

    @Override
    public String getId() {
        return id;
    }

    @Override
    public void setId(String id) {
        this.id = id;
    }

    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
        Collections.reverse(clazzList);
        clazzList.forEach(clazz -> {
            clazz.accept(visitor);
        });
    }

    @Override
    public String getType() {
        return "g";
    }

    public Grade add(Element element) {
        clazzList.add((Clazz) element);
        return this;
    }

    public Grade remove(Element element) {
        clazzList.remove((Clazz) element);
        return this;
    }

    public List<Clazz> getClazzList() {
        return clazzList;
    }

    @Override
    public String getIn() {
        return in;
    }
}
class Student implements Element{
    private String id;
    private String name;
    private int score;
    private String in;

    public Student(String in) {
        this.in = in;
        in = in.replaceAll("\\{","").replaceAll("\\}","");
        this.id = in.split("-")[0];
        this.name = in.split("-")[1];
        this.score = Integer.parseInt(in.split("-")[2].replaceAll("}*",""));
    }

    @Override
    public String getId() {
        return id;
    }

    @Override
    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getScore() {
        return score;
    }

    public void setScore(int score) {
        this.score = score;
    }

    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }

    @Override
    public String getType() {
        return "s";
    }

    @Override
    public String getIn() {
        return in;
    }
}
class VisitorA implements Visitor{
    @Override
    public void visit(Grade grade) {
        System.out.println(grade.getId());
    }

    @Override
    public void visit(Clazz clazz) {
        System.out.println("--"+clazz.getId()+"("+ clazz.getStudentList().size()+")");
    }

    @Override
    public void visit(Student student) {
        String state;
        if (student.getScore()>=60) {
            state = "passed";
        }
        else {
            state = "failed";
        }
        System.out.println("----"+student.getId()+","+student.getName()+","+student.getScore()+","+state);
    }
}
class Main {
    public static void main(String[] args) {
        /*
         * 输入代码,请保留
         * 数组inputs对应控制台输入
         * inputs[0]: 0 - 年级、班级、学生等数据在程序内由createObjectStructure方法创建;
         *            1 - 年级、班级、学生等数据从控制台输入并经过parseInputs方法分析得到;
         * inputs[1]: {g01:{c01:{s01-Jack-80,s02-Tom-70},c02:{s03-Green-90,s04-Smith-70}},g02:{c03:{s05-Jones-75,s06-Jerry-85}}}
         *  */
        Scanner sc = new Scanner(System.in);
        String[] inputs = new String[2];
        for(int i=0;i<inputs.length;i++){
            try {
                inputs[i]=sc.nextLine();
            }
            catch (Exception ignored) {

            }
        }
        sc.close();

        Visitor visitor = new VisitorA();  //创建访问者
        Grade[] grades=null;

        // 根据输入情况来选择采用何种方式创建年级、班级、学生等对象,并将其组合。
        if (Integer.parseInt(inputs[0])==0)
            grades = createObjectStructure();
        else
            grades = parseInputs(inputs[1]);

        for (Grade grade:grades) {
            grade.accept(visitor);  //接受访问者对象,输出结果
        }
    }
    /* 创建年级、班级、学生对象并将其组合起来 */
    public static Grade[] createObjectStructure() {
        /*  创建的年级、班级、学生对象如下:

        年级:g01,该年级有以下班级:
                班级:c101,该班级有以下学生
                        学生:s01,Jack,70
        ----s04,Green,50
        --c102
        ----s02,Tom,80
        ----s05,Smith,60
        g02
        --c103
        ----s03,Jerry,90
        ----s06,Jones,70
        */
        List<Grade> gradeList = new ArrayList<>();
        Grade grade1 = new Grade("g01");
        Grade grade2 = new Grade("g02");
        grade1.add(new Clazz("c101").add(new Student("s01-Jack-70")).add(new Student("s04-Green-50"))).add(new Clazz("c102").add(new Student("s02-Tom-80")).add(new Student("s05-Smith-60")));
        grade2.add(new Clazz("c103").add(new Student("s03-Jerry-90")).add(new Student("s06-Jones-70")));
        Collections.reverse(grade1.getClazzList());
        Collections.reverse(grade2.getClazzList());
        grade1.getClazzList().forEach(clazz -> {
            Collections.reverse(clazz.getStudentList());
        });
        grade2.getClazzList().forEach(clazz -> {
            Collections.reverse(clazz.getStudentList());
        });
        gradeList.add(grade1);
        gradeList.add(grade2);
        return gradeList.toArray(new Grade[0]);
    }

    /* 通过分析strInput字符串创建年级、班级、学生对象并将其组合起来 */
    public static Grade[] parseInputs(String strInput) {
        strInput = strInput.replaceAll(" ","");
        if (strInput.isEmpty()) {
            return new Grade[0];
        }
        List<Grade> gradeList = new ArrayList<>();
        Stack<Element> stack = new Stack<>();
        for (String comma:strInput.split(",")) {
            for (String colon:comma.split(":")) {
                switch(colon.replaceAll("\\{","").replaceAll("\\}","").charAt(0)) {
                    case 'g':
                        stack.push(new Grade(colon));
                        break;
                    case 'c':
                        stack.push(new Clazz(colon));
                        break;
                    case 's':
                        stack.push(new Student(colon));
                        break;
                }
                while (colon.charAt(colon.length()-1) == '}') {
                    List<Element> temp = new ArrayList<>();
                    while (!stack.isEmpty()) {
                        if (stack.lastElement().getIn().charAt(0) == '{') {
                            temp.add(stack.pop());
                            break;
                        }
                        else {
                            temp.add(stack.pop());
                        }
                    }
                    if (!stack.isEmpty()) {
                        Element tempOwner = stack.lastElement();
                        if (tempOwner.getType().equals("g")) {
                            Grade owner = (Grade) tempOwner;
                            temp.forEach(owner::add);
                            gradeList.add(owner);
                        }
                        else if (tempOwner.getType().equals("c")) {
                            Clazz owner = (Clazz) tempOwner;
                            temp.forEach(owner::add);
                        }
                    }
                    colon = colon.substring(0,colon.length()-1);
                }
            }
        }
        return gradeList.toArray(new Grade[0]);
    }
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值