查找重复元素从Java数组中发生两次以上

时间:2018-07-24 14:34:24

标签: java arrays sorting java.util.scanner

我想从数组中找到重复的元素和索引号。我为此写下了代码。它运作良好,但只有当重复元素的数量大于2时,才能生成准确的输出。我从文件中读取值,然后构建一个数组,然后从该数组中搜索重复元素。

import java.io.File;
import java.util.Arrays;
import java.util.Scanner;

public class T1 {
public static void main(String args[]) throws Exception{
    Scanner x=new Scanner(new File("C:\\Duplicate_array.txt"));
    int [] duplicate_data=new int[9];
    int i1=0;
    while(x.hasNext()){
        int a=x.nextInt();
        duplicate_data[i1]=a;
        i1++;
    }
    System.out.println(Arrays.toString(duplicate_data));
    for (int i = 0; i < duplicate_data.length-1; i++) {
        for (int j = i+1; j < duplicate_data.length; j++) {
            if ((duplicate_data[i] == duplicate_data[j]) && (i != j)) {
                System.out.println("Duplicate Element : "+duplicate_data[j]);
                System.out.println("Index of that duplicate element : "+j);
            }
        }
    }
}
}

这是我的输出:

[5, 6, 1, 6, 9, 5, 2, 1, 5]
Duplicate Element : 5
Index of that duplicate element : 5
Duplicate Element : 5
Index of that duplicate element : 8
Duplicate Element : 6
Index of that duplicate element : 3
Duplicate Element : 1
Index of that duplicate element : 7
Duplicate Element : 5
Index of that duplicate element : 8

最后一行错误。它已经在位置8的开头找到了5。但是在程序的结尾,它再次搜索5并给出了位置号。最后的搜索是不必要的。如何摆脱最后的搜索?

4 个答案:

答案 0 :(得分:3)

(i != j)在if语句中不是必需的,因为j总是比i领先1,但这不是您的问题。

您可以尝试使用重复数组标志来了解何时已找到重复项。

import java.util.Arrays;

public class StackOverflow {
    public static void main(String args[]) throws Exception {
        int[] duplicate_data = {5,6,1,6,9,5,2,1,5};
        boolean[] duplicate = new boolean[duplicate_data.length];

        System.out.println(Arrays.toString(duplicate_data));
        for (int i = 0; i < duplicate_data.length - 1; i++) {
            for (int j = i + 1; j < duplicate_data.length; j++) {
                // Make sure you haven't flagged this as a duplicate already
                if (!duplicate[j] && duplicate_data[i] == duplicate_data[j]) {
                    duplicate[j] = true;
                    System.out.println("Duplicate Element : " + duplicate_data[j]);
                    System.out.println("Index of that duplicate element : " + j);
                }
            }
        }
    }
}

结果:

[5, 6, 1, 6, 9, 5, 2, 1, 5]
Duplicate Element : 5
Index of that duplicate element : 5
Duplicate Element : 5
Index of that duplicate element : 8
Duplicate Element : 6
Index of that duplicate element : 3
Duplicate Element : 1
Index of that duplicate element : 7

答案 1 :(得分:1)

它将再次搜索相同的重复项,因为您不会以任何方式存储以前找到的重复项。因此,您必须使用数据结构来存储先前找到的重复项,而不是再次搜索它们。 这使我们有一个更好的解决方案来查找重复项,该解决方案从一开始就使用哈希集,因为它是O(n)而不是O(n ^ 2)

import java.io.File;
import java.util.Arrays;
import java.util.Scanner;

public class T1 {
    public static void main(String args[]) throws Exception {
        Scanner x=new Scanner(new File("C:\\Duplicate_array.txt"));
        Set<Integer> set = new HashSet<Integer>();
        int index = 0;
        while(x.hasNext()){
            int nextNumber = x.nextInt();
            if (set.contains(nextNumber)) {
                System.out.println("Duplicate Element : " + nextNumber);
                System.out.println("Index of that duplicate element : "+index); 
            } else
                set.add(nextNumber);
        }
    }
}

如您所见,使用HashSet时,我们不需要两个嵌套的for循环。我们可以测试HashSet是否包含一个恒定时间O(1)的数字,从而消除了逐个搜索整个数组元素以查找重复项的需要。

答案 2 :(得分:1)

您只想遍历数组一次。如果您想要的只是重复项,则只需在使用ArrayList之前跟踪您看到的任何值即可完成此操作:

int[] data = {5, 6, 1, 6, 9, 5, 2, 1, 5};

System.out.println(Arrays.toString(data));

ArrayList<Integer> seenBeforeList = new ArrayList<>();
for(int index = 0; index < data.length; index++){
    int value = data[index];
    if(seenBeforeList.contains(value)){
        System.out.println("Duplicate Element : " + value);
        System.out.println("Index of that duplicate element : " + index);
    } else {
        seenBeforeList.add(value);
    }
}

输出:

[5, 6, 1, 6, 9, 5, 2, 1, 5]
Duplicate Element : 6
Index of that duplicate element : 3
Duplicate Element : 5
Index of that duplicate element : 5
Duplicate Element : 1
Index of that duplicate element : 7
Duplicate Element : 5
Index of that duplicate element : 8

如果要按值分组,则使用HashMap,将值存储为键,将索引存储为值会更有意义。然后只需遍历HashMap

答案 3 :(得分:-1)

i从0(值5)开始,j从数组的末尾(值5)开始,它输出重复权的位置。但是,当我在数组的末尾而j在结尾的末尾时,它会做同样的事情,要解决此问题,您可以复制数组,并在遍历数组时删除重复项。