Java-递归-线程中的异常;“主要”;栈溢出
我在打印文件依赖项列表时遇到了一个问题 关于该计划:Java-递归-线程中的异常;“主要”;栈溢出,java,recursion,Java,Recursion,我在打印文件依赖项列表时遇到了一个问题 关于该计划: 扫描给定的*.c文件以查找依赖项,更具体地说是查找“#include”%” 找到这些文件并递归扫描它们的依赖关系 所有信息都存储在ConcurrentHashMap(键:字符串值:字符串链表)表中,其中字符串链表包含依赖项列表 在处理某个文件后,我得到以下哈希表: 测试依赖项是否已打印的唯一位置是第一个for循环。您也应该检查第二个for循环 for (String d : dependencies) { if (!alreadyPr
测试依赖项是否已打印的唯一位置是第一个for循环。您也应该检查第二个for循环
for (String d : dependencies) {
if (!alreadyPrinted.containsKey(d)) {
LinkedList<String> key = theTable.get(d);
if (key != null)
output += printDependencies(theTable, key, alreadyPrinted);
}
}
for(字符串d:依赖项){
如果(!alreadyPrinted.containsKey(d)){
LinkedList key=table.get(d);
if(key!=null)
输出+=打印依赖项(表、键、已打印);
}
}
测试依赖项是否已打印的唯一位置是第一个for循环。您也应该检查第二个for循环
for (String d : dependencies) {
if (!alreadyPrinted.containsKey(d)) {
LinkedList<String> key = theTable.get(d);
if (key != null)
output += printDependencies(theTable, key, alreadyPrinted);
}
}
for(字符串d:依赖项){
如果(!alreadyPrinted.containsKey(d)){
LinkedList key=table.get(d);
if(key!=null)
输出+=打印依赖项(表、键、已打印);
}
}
只要某些依赖项看起来像:
item: ...., item, ....
(我听到你说:“那是不可能的,因为……”。然而,SO表明它确实发生了,或者你的堆栈太小了。)
顺便说一句,您维护的映射“已打印”,但它没有被使用?这暗示着您的实现中存在缺陷。很容易看到,一旦某些依赖项看起来像:
item: ...., item, ....
(我听到你说:“那是不可能的,因为……”。然而,SO表明它确实发生了,或者你的堆栈太小了。)
顺便说一句,您维护的映射“已打印”,但它没有被使用?这暗示了您的实现中存在缺陷。当您维护某些状态(已打印和输出)时,我建议将状态移动到实例变量,并使用对象和非类方法。当您维护某些状态时(alreadyPrinted and output)我建议将状态移动到实例变量,并使用对象和非类方法。如果我理解映射输出的意思,则头文件中有一个循环(包含循环)
i_50.h=[i_35.h, i_28.h, i_45.h, i_44.h, i_46.h],
....
i_35.h=[i_50.h, i_51.h]
这意味着您的依赖关系是一个图而不是DAG,这反过来意味着简单的递归遍历将不起作用
从外观上看,您正在尝试进行图形漫游,但由于某些原因,您的循环检测/避免无法工作,并且您的算法进入“无限”递归
查看代码后,我想我可以看到问题所在。在第一种方法中,您检查依赖项是否已打印,然后在
alreadyPrinted
映射中设置条目表示已打印。但是,您随后继续打印它,而不考虑它。然后在第二种方法中,您(莫名其妙地)已打印每次递归到第一个方法时,创建一个新的alreadyPrinted
映射。换句话说,循环避免的逻辑被破坏
与其为您修改代码,我建议您转到您最喜欢的“数据结构和算法”教科书,并在索引中查找“图形遍历”。或者,这里是我在一些在线课堂讲稿中找到的一页:
traverse(Node node):
traverse_0(node, new Set<Node>())
traverse_0(Node node, Set<Node> visited):
if (visited.contains(node))
return
visited.add(node)
for (Node child: node.children)
traverse_o(child, visited)
遍历(节点):
遍历0(节点,新集())
遍历0(节点,访问集):
if(已访问.包含(节点))
返回
已访问。添加(节点)
for(节点子节点:Node.children)
traverse_o(儿童,探访)
如果我理解map输出的意思,那么头文件中有一个循环(include循环)
i_50.h=[i_35.h, i_28.h, i_45.h, i_44.h, i_46.h],
....
i_35.h=[i_50.h, i_51.h]
这意味着您的依赖关系是一个图而不是DAG,这反过来意味着简单的递归遍历将不起作用
从外观上看,您正在尝试进行图形漫游,但由于某些原因,您的循环检测/避免无法工作,并且您的算法进入“无限”递归
查看代码后,我想我可以看到问题所在。在第一种方法中,您检查依赖项是否已打印,然后在
alreadyPrinted
映射中设置条目表示已打印。但是,您随后继续打印它,而不考虑它。然后在第二种方法中,您(莫名其妙地)已打印每次递归到第一个方法时,创建一个新的alreadyPrinted
映射。换句话说,循环避免的逻辑被破坏
与其为您修改代码,我建议您转到您最喜欢的“数据结构和算法”教科书,并在索引中查找“图形遍历”。或者,这里是我在一些在线课堂讲稿中找到的一页:
traverse(Node node):
traverse_0(node, new Set<Node>())
traverse_0(Node node, Set<Node> visited):
if (visited.contains(node))
return
visited.add(node)
for (Node child: node.children)
traverse_o(child, visited)
遍历(节点):
遍历0(节点,新集())
遍历0(节点,访问集):
if(已访问.包含(节点))
返回
已访问。添加(节点)
for(节点子节点:Node.children)
traverse_o(儿童,探访)
问题是我的图形遍历有我没有处理的循环。工作代码是pr