用于计算 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
时,它会给您5
和 10
是,您的 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#filter
和 Set
来生成重复计数
例如...
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
我有以下方法,它采用字符串的 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
时,它会给您5
和 10
是,您的 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#filter
和 Set
来生成重复计数
例如...
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