优化二维数组

时间:2016-09-26 05:47:57

标签: java algorithm data-structures

我有尺寸为720x90的双维数组。我们用R和C表示行作为列。 R1 = {C1,...,C90}

...

R720 = {C1,... C90}

现在,我想查看任何行中的任何数据是否出现在任何其他行的任何其他位置。例如,假设行470和列67中的数据是行672和列34的副本。在这种情况下,我想从数据集中删除行470和行672并继续检查。检查完所有行后,我想只打印幸存行的索引。我写了一个蛮力的方法。但是,当我运行此代码时,它永远不会返回,我无法诊断原因。另外,有更有效的方法吗?

//check all the subsets of the interleaved data
public static int checkSubsets(String[][] subsets){
    List subset = new ArrayList();
    for(int i = 0; i< 720; i++){
        for(int j = 0; j < 90; j++)
            subset.add(subsets[i][j]);
    }
    Object duplicate; 
    Iterator itr = subset.iterator();
    while(itr.hasNext()){    
        duplicate = itr.next();    
        while(itr.hasNext()){    
            subset.remove(duplicate);
            itr=subset.iterator(); //to avoid concurrent modification
            itr.next();    
        }
    }
    return subset.size();
}

澄清:让我们说我正在迭代查看矩阵中的每个值。我取R1 C1中的第一个值(第1行 - 第1列)。我发现这些值可以在12,346,123,356行的某处找到。然后我从矩阵中删除所有这些行。所以现在矩阵要小5行。我现在停止检查第1行并转到第2行。我继续检查,跳过第12,346,123和356行。因此,我在一行之后是唯一的(有90个值都是唯一的)。

2 个答案:

答案 0 :(得分:2)

我不确定你写的代码与要求有什么关系,我会给你答案的方法,但你必须先自己尝试。

很明显,你需要迭代每一行来检查可能的重复但这会导致性能失败,你可以通过使用HashMap克服这个问题,首先将每个条目存储在地图中,关键是数组节点的值,该值应该是该节点的坐标。

当遍历数组的每一行时,您应该找到地图中y坐标,该坐标在行的所有节点之间是通用的,因此检测到重复的行。

为了避免继续检查已删除的行,尝试存储要删除的所有行并在完成后将其删除,您可以使用Set来存储它们以避免重复。

祝好运实。

答案 1 :(得分:0)

该算法几乎存在,但缺少有用的数据结构。

为了添加一些香料,我稍微使用了Java 8。

正如您所做的那样,可以收集值以检查重复项。 但是,需要记住该值的第一行,因为只有在存在重复时仍然未知。

public static int checkSubsets(String[][] subsets) {

    // The results.
    final Set<Integer> duplicateRows = new HashSet<>();

    // From the first occurrence of a duplicate value we do not know it yet,
    // so need to remember.
    final Map<String, Integer> firstRowOfValue = new HashMap<>();

    for (int i = 0; i < subsets.length; ++i) {
        for (int j = 0; j < subsets[i].length; ++j) {
            final String value = subsets[i][j];
            Integer oldRow = firstRowOfValue.putIfAbsent(value, i);
            if (oldRow != null) { // Duplicates
                duplicateRows.add(i);
                duplicateRows.add(oldRow);
                // oldRow might already be added if third duplicate or same row.
            }
        }
    }

    IntStream.rangeOf(0, subsets.length)
        .filter(i -> !duplicateRows.contains(i))
        .forEach(System.out::println);
    return subsets.length - duplicateRows.size();
}

IntStream部分将在java 7中:

for (int i = 0; i < subsets.length; ++i) {
    if (!duplicateRows.contains(i)) {
        System.out.println(i);
    }
}

使用java 7,您可以安全地将putIfAbsent替换为put