You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java分支测验:路径统计方法实现及设计合理性咨询

问题描述

我正在开发一个带分支逻辑的测验项目,使用simple.json库处理JSON数据——后续问题由前序答案决定。相关问题与选项如下:

{"What is your marital status?": ["Single", "Married"]}
{"Are you planning on getting married next year?": ["Yes", "No"]}
{"How long have you been married?": ["Less than a year", "More than a year"]}
{"Have you celebrated your one year anniversary?": ["Yes", "No"]}

我已经实现了测验的分支逻辑,设计了如下结构的JSON配置文件:

{
  "What is your marital status?": {
    "Single": "Are you planning on getting married next year?",
    "Married": "How long have you been married?"
  },
  "Are you planning on getting married next year?": {
    "Yes": "0 Thanks for your answers! We hope that you will build a cool family!",
    "No": "0 Thanks for your answers! Who knows, maybe you'll find someone significant in your life!"
  },
  "How long have you been married?": {
    "Less than a year": "0 Thanks for your answers! We hope that you will celebrate your one year anniversary soon!",
    "More than a year": "Have you celebrated your one year anniversary?"
  },
  "Have you celebrated your one year anniversary?": {
    "Yes": "0 Wow, cool! Keep it up! Thanks for your answers.",
    "No": "0 We think you should fix it next time! Thanks for your answers!"
  }
}

同时编写了QuizHandler类来运行测验:

public class QuizHandler {
    private static final Logger LOGGER = Logger.getLogger("QuizHandler");
    public void runQuiz(JSONObject configuration) {
        List<Object> keys = configuration.keySet().stream().toList();
        LOGGER.info("keys: " + keys);
        String question = "What is your marital status?";
        Scanner scanner = new Scanner(System.in);

        while (question.charAt(0) != '0') {
            System.out.println(question);
            System.out.println("Possible answers: " + ((JSONObject) configuration.get(question)).keySet().toString());
            question = ((JSONObject) configuration.get(question)).get(scanner.nextLine()).toString();
        }
        System.out.println(question.substring(2));
    }
}

配置中以0开头的内容表示测验结束,当前运行逻辑正常。

现在需要实现QuizService类中的方法,统计测验的所有可能路径数量,并生成如下格式的JSON结果:

{
  "paths": {
    "number": 3,
    "list": [
      [{"What is your marital status?": "Single"}, {"Are you planning on getting married next year?": "Yes/No"}],
      [{"What is your marital status?": "Married"}, {"How long have you been married?": "Less than a year"}],
      [{"What is your marital status?": "Married"}, {"How long have you been married?": "More than a year"}, {"Have you celebrated your one year anniversary?": "Yes/No"}]
    ]
  }
}

待实现的类框架:

public class QuizService {
    // TODO: Implement a method that will count the number of possible ways to go through the quiz
}

请问如何实现该方法?当前的测验逻辑设计是否合理?


解决方案

1. 实现路径统计方法

可以采用**深度优先搜索(DFS)**遍历所有可能的测验路径,收集路径信息后生成目标JSON结构。以下是具体实现:

import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class QuizService {

    // 主方法:生成包含路径数量和列表的JSON结果
    public JSONObject generateQuizPaths(JSONObject configuration) {
        List<List<JSONObject>> allPaths = new ArrayList<>();
        // 从起始问题开始遍历
        dfs(configuration, "What is your marital status?", new ArrayList<>(), allPaths);

        // 构建结果JSON
        JSONObject result = new JSONObject();
        JSONObject pathsObj = new JSONObject();
        pathsObj.put("number", allPaths.size());

        JSONArray pathList = new JSONArray();
        for (List<JSONObject> path : allPaths) {
            JSONArray jsonPath = new JSONArray();
            jsonPath.addAll(path);
            pathList.add(jsonPath);
        }
        pathsObj.put("list", pathList);
        result.put("paths", pathsObj);

        return result;
    }

    // 深度优先搜索遍历路径
    private void dfs(JSONObject configuration, String currentQuestion, List<JSONObject> currentPath, List<List<JSONObject>> allPaths) {
        JSONObject questionOptions = (JSONObject) configuration.get(currentQuestion);
        if (questionOptions == null) {
            return;
        }

        // 分类当前问题的选项:指向结束的答案 / 指向后续问题的答案
        Map<String, String> optionsMap = (Map<String, String>) questionOptions;
        List<String> endAnswers = new ArrayList<>();
        List<String> nextQuestionAnswers = new ArrayList<>();

        for (Map.Entry<String, String> entry : optionsMap.entrySet()) {
            String answer = entry.getKey();
            String next = entry.getValue();
            if (next.startsWith("0")) {
                endAnswers.add(answer);
            } else {
                nextQuestionAnswers.add(answer);
            }
        }

        // 处理指向结束的答案:合并为一个路径条目
        if (!endAnswers.isEmpty()) {
            JSONObject questionEntry = new JSONObject();
            questionEntry.put(currentQuestion, String.join("/", endAnswers));
            List<JSONObject> newPath = new ArrayList<>(currentPath);
            newPath.add(questionEntry);
            allPaths.add(newPath);
        }

        // 递归处理指向后续问题的答案
        for (String answer : nextQuestionAnswers) {
            String nextQuestion = optionsMap.get(answer);
            JSONObject singleEntry = new JSONObject();
            singleEntry.put(currentQuestion, answer);
            List<JSONObject> newPath = new ArrayList<>(currentPath);
            newPath.add(singleEntry);
            dfs(configuration, nextQuestion, newPath, allPaths);
        }
    }
}

实现说明

  • 使用DFS递归遍历每个问题的选项,区分选项是指向结束还是下一个问题
  • 对于直接指向结束的多个选项(如Yes/No),合并成一个路径条目,避免生成重复路径
  • 最终收集所有路径后,按照要求的JSON格式组装结果

2. 现有测验逻辑设计合理性分析

优点

  • 结构直观:JSON配置直接映射问题与分支关系,易于理解和维护
  • 逻辑简单:QuizHandler的循环逻辑清晰,通过字符串前缀判断终止条件,实现成本低
  • 扩展性较好:新增问题或分支只需修改JSON配置,无需大量改动Java代码

潜在问题与优化建议

  • 硬编码起始问题:QuizHandler中直接写死起始问题"What is your marital status?",后续修改起始点需改动代码,建议在JSON配置中新增"startQuestion"字段指定起始问题
  • 终止标识脆弱:用0作为结束标识,若后续结束文案出现以0开头的内容会导致逻辑错误,建议改用结构化标识,比如{"type": "end", "message": "xxx"}
  • 缺失输入校验:用户输入无效答案时会直接抛出异常,建议增加输入校验逻辑,提示用户重新输入有效选项
  • 路径统计复杂度高:当前配置依赖字符串前缀判断结束,增加了路径统计的解析成本,改用结构化配置(区分问题节点和结束节点)会让统计逻辑更简洁

内容的提问来源于stack exchange,提问作者Serhii Chernikov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 11:01:12