用于计算 ArrayList 中重复项的嵌套循环无法正常工作

Nested loop to count duplicates in an ArrayList isn't working properly

我有以下方法,它采用字符串的 ArrayList,其中每个字符串都是“(x, y)”形式的坐标。该方法应该计算这些坐标中的任何一个在列表中出现多次的次数。

这是我的代码:

public static int duplicateHouses(ArrayList<String> houses){
        int duplicateCount = 0;

        for(int i = 0; i < houses.size(); i++){
            for(int j = i + 1; j < houses.size(); j++){
                if((houses.get(i)).equals(houses.get(j))){
                    duplicateCount++;
                }
            }
        }

        return duplicateCount;
    }

它最终返回的数字远远大于我列表中的字符串数。我哪里错了?

这是因为你循环了2次,所以每次输入都会告诉你我重复了2次。

假设您在 2、5 和 10 处有相同的 coordinate/house。现在根据现有逻辑,当您的第一个循环是 运行ning for i=2 时,它会给您510 是,您的 duplicateCount 将是 2,这是正确的。但是当你的第一个循环将 运行 用于 i=5 然后它再次给你 YES 10。这就是你会遇到问题的地方。

所以,您可以做的是在您的第一个 FOR 循环中仅增加一次 duplicateCount,这样即使还有 100 个条目,它也不会增加 duplicateCount,它只会增加在第一个 FOR 循环的连续 运行 上,这将防止 duplicateCount.

的重复递增

尝试以下:

public static int duplicateHouses(ArrayList<String> houses){
    int duplicateCount = 0;
    ArrayList<String> dupHouses = new ArrayList<String>;

    for(int i = 0; i < houses.size(); i++){
        for(int j = i + 1; j < houses.size(); j++){
            if((houses.get(i)).equals(houses.get(j))){
                if(!dupHouses.contains(houses.get(j))){
                    duplicateCount++;
                    dupHouses.add(houses.get(j));
                }
            }
        }
        dupHouses = new ArrayList<String>; //Reset for next iteration ...
    }
    return duplicateCount;
}

如果您的 List 中至少有 4 个重复项,第一个循环将找到 3 个,第二个循环将找到 2 个,第三个循环将找到 1 个,结果为 6。基本上,每个循环都再次找到相同的重复项。

例如...

public static void main(String[] args) {
    ArrayList<String> houses = new ArrayList<>(25);
    houses.add("(1x1)");
    houses.add("(1x2)");
    houses.add("(1x1)");
    houses.add("(1x3)");
    houses.add("(1x1)");
    houses.add("(1x4)");
    houses.add("(1x1)");
    houses.add("(1x5)");

    System.out.println(houses.size());
    System.out.println(duplicateHouses2(houses));
}

public static int duplicateHouses(ArrayList<String> houses) {
    int duplicateCount = 0;

    for (int i = 0; i < houses.size(); i++) {
        System.out.println("---");
        for (int j = i + 1; j < houses.size(); j++) {
            if ((houses.get(i)).equals(houses.get(j))) {
                System.out.println(i + ": " + houses.get(i) + " == " + j + ": " + houses.get(j));
                duplicateCount++;
            }
        }
    }

    return duplicateCount;
}

哪个输出...

---
0: (1x1) == 2: (1x1)
0: (1x1) == 4: (1x1)
0: (1x1) == 6: (1x1)
---
---
2: (1x1) == 4: (1x1)
2: (1x1) == 6: (1x1)
---
---
4: (1x1) == 6: (1x1)
---
---
---

现在,您可以创建 List 的副本并在找到时删除每个重复项,或者您可以使用第二个 List 来存储重复值。

我尝试计算 Set 值与原始值 List 之间的差异,但返回的值比预期结果小 1(在上面的示例中,它返回 3 而不是共 4 个)

相反,我使用了原件的 Stream#filterSet 来生成重复计数

例如...

public static int duplicateHouses(ArrayList<String> houses) {
    // Make sure we only have 1 of each possible value
    Set<String> copy = new HashSet<>(houses);
    int duplicateCount = 0;
    // For each value, we want to filter the original 
    // list so that only matching values remain...
    for (String value : copy) {
        Stream<String> filter = houses.stream().filter((String t) -> t.equals(value));
        // If there is more then one, then there are duplicates...
        long count = filter.count();
        if (count > 1) {
            duplicateCount += count;
        }
    }
    return duplicateCount;
}

对于第一个例子,returns 3