从文本文件创建迷宫图:Java

时间:2011-06-02 03:06:52

标签: java graph maze

我需要从包含多个'迷宫'的文本文件中创建一个图形,表示为邻接列表。清单如下:

A,G
A,B,F
B,A,C,G
C,B,D,G
D,C,E
E,D,F,G
F,A,E
G,B,C,E

D,F
A,B,G
B,A,C,E,G
C,B,D,E,G
D,C
E,B,C,G
F,G
G,A,B,C,E,F

F,A
A,B,G
B,A,G
C,D,G
D,C,G
E,F,G
F,E,G
G,A,B,C,D,E,F

每个'迷宫'的第一行包含迷宫的起始节点(第一个字母)和迷宫的结束节点(第二个字母)。

我已将文本文件解析为所有行(包括空行)的ArrayList,然后解析为ArrayLists行的ArrayList(单独的迷宫列表)。我通过在空行上分割完整的文本来做到这一点。我现在的问题是我无法弄清楚如何使用我的节点类从这些“迷宫”构建图形。这是我的节点类:

package algo2;

import java.util.ArrayList;


public class Node<T>{

    private T value; //this Node<T>'s value
    public ArrayList<Node<T>> connections;
    public boolean isStart;
    public boolean isEnd;
    public boolean visited;

    public Node(T value){
        this.value = value;
        connections = new ArrayList<Node<T>>();
    }

    //returns the value of this Node<T>
    public T getValue(){
        return value;
    }

    //returns true if the node is connected to any other nodes
    public boolean isConnected(){
        if(connections == null){
            return false;
        }
        return true;
    }

    //returns a list of nodes connected to this node
    public ArrayList<Node<T>> getConnections(){
        return connections;
    }

    //sets the node's value
    public void setValue(T value){
        this.value = value;
    }

    //adds a connection from this node to the passed node
    public void connect(Node<T> node){
        connections.add(node);
    }

    public String toString(){
        return value+"";
    }
}

有人能指出我正确的方向吗?

3 个答案:

答案 0 :(得分:1)

让我们专注于设置1个迷宫,然后我们可以重复所有这些过程。 我试图编写一个Java语法友好的算法。

所以,这是第一个迷宫的ArrayList变量,据我所知......

List<String> preNodes, which contains:
{"A,G", "A,B,F", "B,A,C,G", "C,B,D,G", "D,C,E", "E,D,F,G", "F,A,E", "G,B,C,E"};

因为第一个String具有特殊含义,所以让它与其余字符串分开。 (即将其设置为单独的String变量,并将其从ArrayList中删除)。

String startAndEnd, which contains: "A,G";
List<String> preNodes, which contains: 
{"A,B,F", "B,A,C,G", "C,B,D,G", "D,C,E", "E,D,F,G", "F,A,E", "G,B,C,E"};

现在,让我们首先构建我们需要的所有节点,然后我们可以将它们链接起来。

//Define container for nodes
HashMap<String, Node> nodes = new HashMap<String, Node>();
//Create a node for each letter
for(String s : preNodes) {
    String nodeName = s.charAt(0) + "";
    nodes.put(nodeName, new Node());
}
//Link them up appropriately
for(String s : preNodes) {
    String[] splitS = s.split(","); //1 letter in each array cell.
    Node current = nodes.get(splitS[0]); //Get the node we're going to link up.
    for(int i=1; i<splitS.length; i++) {
        current.connect(nodes.get(splitS[i]));
    }
}
//Finally, set the start and end Node.
String[] splitStartAndEnd = startAndEnd.split(",");
nodes.get(splitStartAndEnd[0]).isStart = true;
nodes.get(splitStartAndEnd[1]).isEnd = true;

我认为应该这样做;现在“节点”包含整个迷宫,全部链接起来。我在你的代码中发现了一个错误:你的isConnected()函数应该在connections.isEmpty()时返回false,而不是如果它为null。它永远不应该为null,因为您在构造函数中使用新列表初始化它。

答案 1 :(得分:0)

您应该在单独的类中编写其他代码来构建迷宫。它将采用文本输入,并输出一组连接的节点。节点本身不应该“构造”任何东西 - 它们只是构建块。

以下是一些如何连接它们的伪代码:

nameToNodeMap -> dictionary of string to node
for each line in the file
    previous token = null
    loop:
    try to get a token (letter, separated by commas)
    if there was no token
        break out of the loop
    else
        if nameToNodeMap contains that token
            get the node for that token
        else
            create a node
            add it to nameToNodeMap, with the token as the key
        if previous node != null
            link previous node to this node
        previous nope = current node
        goto loop

答案 2 :(得分:0)

一种解决方案是使用适当的Node构造函数对输入使用split()(请注意,为简单起见,我已将参数T替换为String):

class Node {
    public String value;
    public String[] connections;
    public boolean visited;

    public Node (String value, String[] connections) {
        this.value = value;
        this.connections = connections;
        visited = false;
    }

    public boolean isConnected(Node that) {
        boolean res = false;
        for (int i=0; !res && i<this.connections.length; i++) {
            res = (this.connections[i] == that.value);
        }
        return res;
    }

    // more stuff ... :)
}

//read start, end nodes

ArrayList<Node> nodes = new ArrayList<Node>();
for (each line in maze) {
    String[] nodeList = line.split(",");
    nodes.add(nodeList[0], Arrays.copyOfRange(nodeList, 1, nodeList.length));
}

我认为这比尝试维护每个节点内的节点列表更简单,只要应用程序的其余部分可以轻松检查两个节点是否已连接或是否已访问过。 (另请注意,您可能希望向Node类添加更多代码以跟踪开始和结束节点。)