Finding Duplicates in Array and printing them only

2019-02-26 07:12发布

I am trying to loop through my array and find all the numbers that are repeating more than once:

E.G: if there is 1 1 2 3 4

It should print saying "1 repeats more than once"

Here is my code and so far what I have tried, however it prints all duplicates and keep going, if there is 4 4 4 4 3 6 5 6 9, it will print all the 4's but i dont want that:

class average {

 public static void main(String[] args) throws IOException {

    int numOfLines = 0;
    int sum = 0, mean = 0, median = 0, lq = 0, uq = 0;
    int[] buffer;

    File myFile = new File("num.txt");
    Scanner Scan = new Scanner(myFile);

    while(Scan.hasNextLine()) {
        Scan.nextLine();
        numOfLines++;
    }
    Scan.close();
    Scan = new Scanner(myFile);

    System.out.println("Number Of Lines: " + numOfLines);

    buffer = new int[numOfLines];

    for(int i=0; i<numOfLines; i++) {
        buffer[i] = Scan.nextInt();
    }
    Scan.close();
    Scan = new Scanner(myFile);

    for(int i=0; i<buffer.length; i++) {
        sum = sum+i;
        mean = sum/numOfLines;
    }
    System.out.println("Sum: " + sum);
    System.out.println("Mean: " + mean);

    for(int i=0; i<buffer.length; i++) {
        for(int k=i+1; k<buffer.length; k++) {
            if(buffer[k] == buffer[i]) {
                System.out.println(buffer[k]);
            }
        }
    }

6条回答
\"骚年 ilove
2楼-- · 2019-02-26 07:15

Just add the number you will find duplicated to some structure like HashSet or HashMap so you can find it later when you will detect another duplication.

Set<Integer> printed = new HashSet<Integer>();

  for(int i=0; i<buffer.length; i++) {
    for(int k=i+1; k<buffer.length; k++) {
      if(buffer[k] == buffer[i]) {
        Integer intObj = new Integer(buffer[k]);
        if (!printed.contains(intObj)) {
          System.out.println(buffer[k]);
          printed.add(intObj);
        }
        break;
       }
    }
  }

Better O(n) alghorithm:

Set<Integer> printed = new HashSet<Integer>();

  for(int i=0; i<buffer.length; i++) {
    if (!printed.add(new Integer(buffer[i])) {
       System.out.println(buffer[i]);
    }
  }
查看更多
对你真心纯属浪费
3楼-- · 2019-02-26 07:35

Using the apache commons CollectionUtils.getCardinalityMap(collection):

  final Integer[] buffer = {1, 2, 3, 4, 5, 6, 7, 2, 1, 7, 9, 1, 1, 3};
  final List<Integer> list = Arrays.asList(buffer);
  final Map<Integer, Integer> cardinalityMap = CollectionUtils.getCardinalityMap(list);
  for (final Map.Entry<Integer, Integer> entry: cardinalityMap.entrySet()) {
    if (entry.getValue() > 1) {
      System.out.println(entry.getKey());
    }
  }

toString() of cardinalityMap looks like this after the init:

{1=4, 2=2, 3=2, 4=1, 5=1, 6=1, 7=2, 9=1}

Using standard java:

  final Integer[] buffer = {1, 2, 3, 4, 5, 6, 7, 2, 1, 7, 9, 1, 1, 3};
  final List<Integer> list = Arrays.asList(buffer);
  final Set<Integer> set = new LinkedHashSet<Integer>(list);
  for (final Integer element: set) {
    if (Collections.frequency(list, element) > 1) {
      System.out.println(element);
    }
  }
查看更多
叛逆
4楼-- · 2019-02-26 07:36

You perform the check for every single item of the array, including the first 4, the second 4 and so on. That's why it just doesn't stop and it prints the message multiple times per duplicated element.

You're saying you cannot use a Set and that you don't want to sort your data. My suggestion is that you loop over the array and add each duplicated item to a list. Make sure you check whether the item has already been added. (or use a Set :) )

Then loop over the list and print those items.

查看更多
贼婆χ
5楼-- · 2019-02-26 07:37

This problem is much simpler and likely faster to solve using a collection. However, as requested here's an answer that uses "just simple array[s]" and no sorting. I've tried not to change your code too much but I refuse to leak resources in the case of an exception.

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

class Average {

     public static void main(String[] args) throws IOException {

        int numOfLines = 0;
        int sum = 0, mean = 0, median = 0, lq = 0, uq = 0;
        int[] buffer;
        int flag = -1;

        File myFile = new File("num.txt");
        try (Scanner Scan = new Scanner(myFile)) {

            while(Scan.hasNextLine()) {
                Scan.nextLine();
                numOfLines++;
            }
        }
        try (Scanner Scan = new Scanner(myFile)) {

            System.out.println("Number Of Lines: " + numOfLines);

            buffer = new int[numOfLines];

            for(int i=0; i<numOfLines; i++) {
                buffer[i] = Scan.nextInt();
            }
        }

        for(int i=0; i<buffer.length; i++) {
            sum = sum+i;
            mean = sum/numOfLines;
        }
        System.out.println("Sum: " + sum);
        System.out.println("Mean: " + mean);

        //copy every duplicate
        int[] dupesOnly = new int[numOfLines];
        int dupesOnlyIndex = 0;
        for(int i=0; i<buffer.length; i++) {
            for(int k=i+1; k<buffer.length; k++) {
                if(buffer[k] == buffer[i]) {
                    dupesOnly[dupesOnlyIndex++] = buffer[i];
                    //System.out.println(buffer[k]);
                }
            }
        }

        //mark all but first occurrence of dupe
        boolean[] skip = new boolean[dupesOnlyIndex]; //Inits to false
        for (int i = 0; i < dupesOnlyIndex; i++) {
            for(int k=i+1; k<buffer.length; k++) {
                if(dupesOnly[k] == dupesOnly[i]) {
                    skip[k] = true;
                }
            }
        }

        //skip elements marked as extra dupes
        int[] dupesUnique = new int[dupesOnlyIndex];
        int dupesUniqueIndex = 0;
        for (int i = 0; i < dupesOnlyIndex; i++) {
            if (skip[i] == false) {
                dupesUnique[dupesUniqueIndex++] = dupesOnly[i];
            }
        }     

        //trim to size
        int[] dupesReport = new int[dupesUniqueIndex];
        for (int i = 0; i < dupesReport.length; i++) {
            dupesReport[i] = dupesUnique[i];
        }

        System.out.println("Dupes: " + Arrays.toString(dupesReport));
    }
}

Input file "num.txt" (numbers separated by newlines not commas):

1, 2, 3, 4, 5, 6, 7, 2, 1, 7, 9, 1, 1, 3

Output:

Number Of Lines: 14
Sum: 91
Mean: 6
Dupes: [1, 2, 3, 7]
查看更多
你好瞎i
6楼-- · 2019-02-26 07:38

I would use a HashMap to store the value I encounter in the array, with the count as a value. So if you encounter a 4, you would look it up in the HashMap, if it doesn't exist, you would add it with a value of 1, otherwise increment the value returned.

You can the loop over the HashMap and get all the values and print the number of duplicates encountered in the array.

查看更多
女痞
7楼-- · 2019-02-26 07:40
Integer[] ints = {1, 1, 2, 3, 4};

System.out.println(new HashSet<Integer>(Arrays.asList(ints)));

Output: [1, 2, 3, 4]

查看更多
登录 后发表回答