Hashmap图形输出错误

时间:2015-03-13 00:32:43

标签: java graph hashmap

我正在使用文本文件,其中第一列代表课程,其他列是该课程的先决条件。

CS1 None
CS2 CS1
CS3 CS2
CS4 CS1
CS5 CS3 CS4
CS6 CS2 CS4

我想逐行进行并创建每行第一个索引的键值 并且值是索引0之后的索引。

例如,行CS6 CS2 CS4CS6作为键(课程),其值(先决条件)将为CS2, CS4

CS6CS4作为邻居,CS4CS2作为其邻居。

但我的输出如下:

CS1:  None, CS1
CS3:  CS2, CS3
CS2:  CS1, CS2
CS5:  CS3, CS5
CS4:  CS1, CS4
CS6:  CS2, CS6
None:

我试图获得如下输出:

CS1:
CS3:  CS2
CS2:  CS1
CS5:  CS3, CS4
CS4:  CS1
CS6:  CS2, CS4

我的构造函数(它给出了错误的输出):

public Graph(String filename) throws FileNotFoundException {
    // open the file for scanning
    File file = new File(filename);
    Scanner in = new Scanner(file);
    // create the graph
    graph = new HashMap<String, Node>();

    // loop over and parse each line in the input file
    while (in.hasNextLine()) {
        // read and split the line into an array of strings
        // where each string is separated by a space.
        Node n1;
        Node n2;
        String line = in.nextLine();
        String[] fields = line.split(" ");

        // creates new nodes as necessary
        if (graph.containsKey(fields[0])) {
            n1 = graph.get(fields[0]);
        }
        else {
            n1 = new Node(fields[0]);
            graph.put(fields[0], n1);
        }
        if (graph.containsKey(fields[1])) {
                n2 = graph.get(fields[1]);
        }
        else {
            n2 = new Node(fields[1]);
            graph.put(fields[1],  n2);
        }

        n1.addNeighbor(n2);
        n1.addNeighbor(n1);
        }
        in.close();
    }

addNeighbor方法:

/**
 * Add a neighbor to this node.  Checks if already present, and does not
 * duplicate in this case.
 *
 * @param n: node to add as neighbor.
 */
public void addNeighbor(Node n) {
    if(!neighbors.contains(n)) {
        neighbors.add(n);
    }
}

...和我的Node构造函数:

/*
 * Neighbors of this node are stored as a list (adjacency list).
 */
private List<Node> neighbors;

/**
 * Constructor.  Initialized with an empty list of neighbors.
 *
 * @param name string representing the name associated with the node.
 */
public Node(String name) {
    this.name = name;
    this.neighbors = new LinkedList<Node>();
}

编辑:我想用我的邻居解决这个问题的方法,我的输出结果来自我打印我的地图。我只是试图通过仅改变构造函数来解决这个问题。

1 个答案:

答案 0 :(得分:1)

1。找到合适的数据结构

您当前的数据结构似乎过于复杂,这可能会导致您在填写错误时出错,并在迭代时显示错误。

最简单

根据您的目标输出,您似乎不希望在结构中具有传递依赖性。您只想输出课程的直接子项(直接依赖项)。

因此,您的数据结构不应该只是一个图表,而只是每个课程到其要求列表的地图:

Map<String, List<String>> requirements = new HashMap<>();

保持图表的想法

如果您需要更复杂的数据或者您确实需要传递依赖项,那么您可以使用课程图以及现有课程的字典(以重用对象)。但是,在这种情况下,我建议你的Course类(或者你喜欢的Node类)包含课程的要求(孩子)而不是邻居。

// this is the dictionary, the Node objects themselves contain the dependencies
Map<String, Course> courses = new HashMap<>();

// your Node class (I renamed to make the purpose of the objects more readable)
class Course {
    private List<Course> requirements = new LinkedList<>();

    public Course(String name) {
        this.name = name;
    }

    public void addRequirement(Course n) {
        requirements.add(n);
    }

    public List<Course> getRequirements() {
        return requirements;
    }
}

2。解决你的问题

您目前不是每次都在阅读整行。获取行的第一个元素后,您应该遍历其他元素以将其添加为需求。

在这里,您只读取数组的索引0和1,这应该告诉您,您忘记了潜在的其他要求。

此外,这里有一些问题:

n1.addNeighbor(n2); // why is the 1st requirement a neighbour of his parent?
n1.addNeighbor(n1); // why is the parent a neighbour of himself ?