我有一个hashmap形式的可达性矩阵。键是行号,值是可达性矩阵非零的列列表。我想从这个矩阵生成先行集。它是通过读取每列的非零条目而开发的。矩阵有5000行。如果我想使用for循环来检查每个键的值集中是否存在每个键,则迭代次数为i 5000 * 5000。我想避免这种情况。是否有任何有效的算法可以避免这么多迭代。
答案 0 :(得分:1)
我认为最好的方法是迭代矩阵中 的值,而不是 在矩阵中的值。由于矩阵是按行而不是按列组织的,这意味着以相同的方式导航:
final Map<Integer, List<Integer>> reverseReachabilityMatrix = new HashMap<>();
for (final Map.Entry<Integer, List<Integer>> reachabilityMatrixRow :
reachabilityMatrix.entrySet()) {
final Integer rowNumber = reachabilityMatrixRow.getKey();
final List<Integer> columnNumbers = reachabilityMatrixRow.getValue();
for (final Integer columnNumber : columnNumbers) {
if (!reverseReachabilityMatrix.containsKey(columnNumber)) {
reverseReachabilityMatrix.put(columnNumber, new ArrayList<>());
}
reverseReachabilityMatrix.get(columnNumber).add(rowNumber);
}
}
(其中reverseReachabilityMatrix
只是同一矩阵的列式表示。)
(注意:reverseReachabilityMatrix
中的结果列表不会有任何有意义的顺序。如果您需要它们,那么您需要以某种方式调整上述内容。例如,您可以使用for (int rowNumber = 1; rowNumber <= numRows; ++rowNumber)
而不是按内部顺序迭代HashMap。)
顺便提一下,虽然我保留了上面的HashMap<Integer, List<Integer>>
结构以保持与您已经拥有的结果的一致性,但我必须说HashMap<Integer, List<Integer>>
在这里似乎不是正确的数据结构,对于两个原因:
contains
在这里是一个常见的操作;您经常需要检查给定行号的可达性列表是否包含给定的列号。因此,Set
,例如TreeSet
似乎更合适。 (使用ArrayList
时,contains
方法必须遍历整个列表。)答案 1 :(得分:0)
您是否考虑将非零元素存储在较小的矩阵中并保留每列的零元素计数?