【问题标题】:Find duplicate element occur more than two times from an array in java从java中的数组中查找重复元素出现两次以上
【发布时间】:2018-07-24 14:34:24
【问题描述】:

我想从数组中找出重复的元素和索引号。我为此写了一个代码。它运行良好,但仅在重复元素数量超过 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 并给出位置号。最后的搜索是不必要的。如何摆脱最后一次搜索?

【问题讨论】:

  • 您能否添加一个输入示例?谢谢
  • 您可以在算法中使用Set 还是只需要使用普通数组?

标签: java arrays sorting java.util.scanner


【解决方案1】:

(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

【讨论】:

    【解决方案2】:

    您只想遍历数组一次。如果你想要的只是重复,你可以简单地通过跟踪你在使用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】:

      它再次搜索相同的重复项,因为您没有以任何方式存储以前找到的重复项。因此,您必须使用数据结构来存储以前找到的重复项,而不是再次搜索它们。 这将我们带到一个更好的解决方案来查找从一开始就使用哈希集的重复项,因为它是 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) 内包含一个数字,这样就无需逐个元素地搜索整个数组来查找重复项。

      【讨论】:

      • 请记住HashSet 的最坏情况或只有平均情况为O(1) 的任何哈希实现。最坏的情况是O(lg(n)) 用于 Java 8,O(n) 用于 Java 7。有关详细信息,请参阅:stackoverflow.com/a/51199917/5065400。对于小尺寸,这是一个小问题,但需要注意。
      【解决方案4】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-04-17
        • 2020-10-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-06-19
        • 2017-03-11
        相关资源
        最近更新 更多