开发者

Creating a maze graph from a text file : Java

I need to make a graph from a text file containing multiple 'mazes' represented as adjacency lists. The list is as follows:

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

The first line of each 'ma开发者_如何转开发ze' contains the starting node of the maze (first letter) and the ending node of the maze (second letter).

I've parsed the text file into an ArrayList of all lines (including blank lines), then into an ArrayList of ArrayLists of lines (a list of separate mazes). I did this by splitting the complete text on blank lines. My problem is now that I cannot figure out how to use my node class to construct a graph from these 'mazes'. Here's my node class:

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+"";
    }
}

Can someone point me in the right direction, please?


Let's concentrate on just setting up 1 maze, and then we can repeat the process for all of them. I've tried to write a Java-syntax-friendly algorithm.

So, here's our ArrayList variable for the first maze, as I understand it...

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"};

Because the first String has a special meaning, let's segregate it from the rest. (ie. set it as a separate String variable, and remove it from the 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"};

Now, let's first build all the nodes we need, and then we can link them up.

//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;

This should do it, I think; now "nodes" contains the whole maze, all linked up. I caught a bug in your code, though: your isConnected() function should return false if connections.isEmpty(), not if it's null. It should never be null, because you initialize it in the constructor with a new list.


You should write additional code in a separate class to construct the maze. It will take textual input, and ouput a set of connected nodes. The nodes themselves shouldn't "construct" anything - they're just building blocks.

Here is some pseudo-code for how to connect them:

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


One solution would be to use split() on the input with an appropriate Node constructor (note that I have substituted String for the parameter T for simplicity):

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));
}

I think this would be simpler than trying to maintain a list of Nodes inside each Node, as long as the rest of your application makes it easy to simply check if two Nodes are connected or if one has been visited. (also note that you would probably want to add more code to the Node class to keep track of the start and end nodes.)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜