【问题标题】:Backtracking using loops in java?在java中使用循环回溯?
【发布时间】:2015-11-20 08:00:37
【问题描述】:

这是我的代码的要点和它的功能。这是一个选择你去哪里的游戏来选择你的路径。例如,如果您在开始时选择路径 a,则可以在路径 d 和 e 之间进行选择,如果您选择了 d,则可以移动到 f 和 g 等等。

我想添加回溯。例如,如果我一开始选择a,然后一直到f,我希望能够回到d,再次在f和g之间进行选择,或者一直回到起点并选择b.

我最初的想法是在我需要回溯时使用一些东西来告诉代码回到某一行代码,但据我了解,java 中没有 goto。我有使用循环的想法。 (我特别想 while 循环。)我不知道如何构造循环以回溯。

这是我的代码:

public class PathGame {

public static void main (String[] args) {

String name = JOptionPane.showInputDialog("Hello! Welcome to my paths! What is your name, adventurer?");
JOptionPane.showMessageDialog(null, "Well then " + name + ", here's how this works...some generic instructions");

String startingChoice = JOptionPane.showInputDialog("Choose your path, a, b, or c.");

if (startingChoice.equals("a")){
String aChoice = JOptionPane.showInputDialog("Choose path d or path e");

if (aChoice.equals("d")) {
    String dExamineChoice = JOptionPane.showInputDialog("path f or g?");
   if (dExamineChoice.equals("f")) {
    JOptionPane.showMessageDialog(null, name + "...!");
   }
   else if (dExamineChoice.equals("g")) {
    JOptionPane.showMessageDialog(null, "Stuff g");
   }
}
else if (aChoice.equals("e")) {
   JOptionPane.showMessageDialog(null, "Stuff e");
}
else if (aChoice.equals("goBack")) {
    ///Backtrack back to start
}
}
else if (startingChoice.equals("b")) {
String bChoice = JOptionPane.showInputDialog("Path h or i?");
if (bChoice.equals("h")) {
    String hChoice = JOptionPane.showInputDialog("Path j, k, or l?");
    if (hChoice.equals("j")) {
        String jExamine = JOptionPane.showInputDialog("m or n?");
        if (jExamine.equals("m")) {
            JOptionPane.showMessageDialog(null,"Stuff m");
        }
        else if (jExamine.equals("n")) {
           JOptionPane.showMessageDialog(null,"Stuff n");
        }
    }
    else if (hChoice.equals("k")) {
        JOptionPane.showMessageDialog(null,"Stuff k");
    }
    else if (hChoice.equals("l")) {
        JOptionPane.showMessageDialog(null,"Stuff l");
    }
    }
else if (bChoice.equals("i")) {
    JOptionPane.showMessageDialog(null,"Stuff i");
}
    }
}
}

【问题讨论】:

  • 您需要将可能的选择存储在图形数据结构中:从根节点开始,边到节点abc,从a 那里是de 等的边...然后用户选择只是此图中遍历节点的列表(即路径)。要返回,只需从列表中删除最后一个条目。
  • 请原谅我,但我不熟悉那种图形数据结构。我该怎么做呢?我明白你在实际层面上所说的话,我只是不知道如何将其翻译成代码,如果这有意义的话。

标签: java loops if-statement nested-if


【解决方案1】:

回溯可以通过递归来实现。但是,因为您想要迭代方法。您可以使用堆栈应用相同的概念。每次访问新方块时,将当前状态推入堆栈。当你需要回溯时(例如你处于死胡同),从堆栈中弹出。

如果您的意图是创建类似迷宫赛跑者的东西,您可能需要记录访问过的方格。

是的,您应该使用 while 循环来做到这一点。

【讨论】:

    【解决方案2】:

    为每个起始选择创建一个选项,这样当用户选择该选项时,startingChoice 设置为您要返回的字母。

    【讨论】:

    • 也许我弄错了,但是如果没有循环,我不会只是在 ifs ad infinitum 上做 ifs 吗?我觉得我必须一遍又一遍地重写代码。除非我错过了你所说的,我承认很可能是。
    【解决方案3】:

    有两种方法可以做到这一点。

    可扩展的方式是使用图形数据结构。你可以使用JGraphTTinkerPop 之类的东西。但这是假设你想要一些真正花哨的东西。图表可以让您非常笼统地对待整个路径选择(遍历)。它可以让你设计各种路径,而回溯只会跟踪你来自哪里。

    更快的方法是使用Stack 数据结构。每次您做出选择时,都会将该选择添加到您的堆栈中。因此,您当前的位置始终存储在堆栈的顶部。当您回溯时,只需从堆栈顶部弹出并重试。例如:

    public static void main(String []){
        Stack<String> myPath = new Stack<>();
        while(detinationNotReached){
            myPath = goSomewhere(myPath);
        }
    }
    public Stack goSomewhere(Stack<String> myPath){
        String currentPosition = myPath.peek();
        String choice = getChoice(currentPosition);
        switch(choice){
            case "a":
                myPath.push("a");
            break;
            ... //Other choices
            case "back":
                myPath.pop(); // This effectively backtracks.
            break;
        }
        return myPath
    }
    

    【讨论】:

      【解决方案4】:

      这是一个如何将可能性存储在图形数据结构中的示例(即half-edge data structure):

      class Edge {
          public final Node end;
          public Edge(Node end) { this.end = end; }
      }
      
      class Node {
          public final int id;
          public final List<Edge> edges;
          public Node(int id, List<Edge> edges) { this.id = id; this.edges = Collections.unmodifiableList(edges); }
      }
      
      class Graph {
          private final ArrayList<ArrayList<Edge>> halfEdges = new ArrayList<>();
          private final ArrayList<Node> nodes = new ArrayList<>();
      
          public Node addNode() {
              ArrayList<Edge> edges = new ArrayList<>();
              Node node = new Node(nodes.size(), edges);
              halfEdges.add(edges);
              nodes.add(node);
              return node;
          }
      
          public Edge addEdge(Node from, Node to) {
              assert nodes.contains(from) && nodes.contains(to);
              Edge edge = new Edge(to);
              halfEdges.get(from.id).add(edge);
              return edge;
          }
      }
      

      你会这样使用它:

      class Game
      {
          public static void main (String[] args)
          {
              Graph graph = new Graph();
              Node root = graph.addNode();
              Node a = graph.addNode();
              graph.addEdge(root, a);
              Node b = graph.addNode();
              graph.addEdge(root, b);
              Node c = graph.addNode();
              graph.addEdge(root, c);
              Node d = graph.addNode();
              graph.addEdge(a, d);
              Node e = graph.addNode();
              graph.addEdge(a, e);
              // ...
      
              // main loop
              ArrayList<Node> path = new ArrayList<>();
              StringBuilder builder = new StringBuilder();
              while(true) {
                  if(path.isEmpty())
                      path.add(root);
                  Node pos = path.get(path.size() - 1);
                  builder.setLength(0);
                  builder.append("At ").append(pos.id).append(", choices: back");
                  for(Edge out : pos.edges)
                      builder.append(", ").append(out.end.id);
                  System.out.println(builder.toString());
                  // handle input: add chosen node to path or remove last entry if "back"
                  // ...
              }
          }
      }
      

      您可以将任何类型的数据添加到NodeEdge,例如用于显示选择的实际名称(而不是id)等...

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-05-27
        • 2019-06-13
        • 2013-08-07
        • 1970-01-01
        • 1970-01-01
        • 2018-08-08
        • 2013-08-05
        相关资源
        最近更新 更多