我正在使用文本文件,其中第一列代表课程,其他列是该课程的先决条件。
CS1 None
CS2 CS1
CS3 CS2
CS4 CS1
CS5 CS3 CS4
CS6 CS2 CS4
我想逐行进行并创建每行第一个索引的键值 并且值是索引0之后的索引。
例如,行CS6 CS2 CS4
将CS6
作为键(课程),其值(先决条件)将为CS2, CS4
。
CS6
将CS4
作为邻居,CS4
将CS2
作为其邻居。
但我的输出如下:
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>();
}
编辑:我想用我的邻居解决这个问题的方法,我的输出结果来自我打印我的地图。我只是试图通过仅改变构造函数来解决这个问题。
答案 0 :(得分: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;
}
}
您目前不是每次都在阅读整行。获取行的第一个元素后,您应该遍历其他元素以将其添加为需求。
在这里,您只读取数组的索引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 ?