Java Array, Finding Duplicates

前端 未结 14 850
闹比i
闹比i 2020-11-22 09:13

I have an array, and am looking for duplicates.

duplicates = false;
for(j = 0; j < zipcodeList.length; j++){
    for(k = 0; k < zipcodeList.length; k++         


        
相关标签:
14条回答
  • 2020-11-22 09:52

    You can use bitmap for better performance with large array.

        java.util.Arrays.fill(bitmap, false);
    
        for (int item : zipcodeList)
            if (!bitmap[item]) bitmap[item] = true;
            else break;
    

    UPDATE: This is a very negligent answer of mine back in the day, keeping it here just for reference. You should refer to andersoj's excellent answer.

    0 讨论(0)
  • 2020-11-22 09:56
    import java.util.Scanner;
    
    public class Duplicates {
        public static void main(String[] args) {
            Scanner console = new Scanner(System.in);
            int number = console.nextInt();
            String numb = "" + number;
            int leng = numb.length()-1;
    
            if (numb.charAt(0) != numb.charAt(1)) {
                System.out.print(numb.substring(0,1));
            }
    
            for (int i = 0; i < leng; i++){
    
              if (numb.charAt(i)==numb.charAt(i+1)){ 
                 System.out.print(numb.substring(i,i+1));
              }
              else {
                  System.out.print(numb.substring(i+1,i+2));
              }
           }
       }
    }
    
    0 讨论(0)
  • 2020-11-22 09:57

    Cause you are comparing the first element of the array against itself so It finds that there are duplicates even where there aren't.

    0 讨论(0)
  • 2020-11-22 10:02

    On the nose answer..

    duplicates=false;
    for (j=0;j<zipcodeList.length;j++)
      for (k=j+1;k<zipcodeList.length;k++)
        if (k!=j && zipcodeList[k] == zipcodeList[j])
          duplicates=true;
    

    Edited to switch .equals() back to == since I read somewhere you're using int, which wasn't clear in the initial question. Also to set k=j+1, to halve execution time, but it's still O(n2).

    A faster (in the limit) way

    Here's a hash based approach. You gotta pay for the autoboxing, but it's O(n) instead of O(n2). An enterprising soul would go find a primitive int-based hash set (Apache or Google Collections has such a thing, methinks.)

    boolean duplicates(final int[] zipcodelist)
    {
      Set<Integer> lump = new HashSet<Integer>();
      for (int i : zipcodelist)
      {
        if (lump.contains(i)) return true;
        lump.add(i);
      }
      return false;
    }
    

    Bow to HuyLe

    See HuyLe's answer for a more or less O(n) solution, which I think needs a couple of add'l steps:

    static boolean duplicates(final int[] zipcodelist)
    {
       final int MAXZIP = 99999;
       boolean[] bitmap = new boolean[MAXZIP+1];
       java.util.Arrays.fill(bitmap, false);
       for (int item : zipcodeList)
         if (!bitmap[item]) bitmap[item] = true;
         else return true;
       }
       return false;
    }
    

    Or Just to be Compact

    static boolean duplicates(final int[] zipcodelist)
    {
       final int MAXZIP = 99999;
       boolean[] bitmap = new boolean[MAXZIP+1];  // Java guarantees init to false
       for (int item : zipcodeList)
         if (!(bitmap[item] ^= true)) return true;
       return false;
    }
    

    Does it Matter?

    Well, so I ran a little benchmark, which is iffy all over the place, but here's the code:

    import java.util.BitSet;
    
    class Yuk
    {
      static boolean duplicatesZero(final int[] zipcodelist)
      {
        boolean duplicates=false;
        for (int j=0;j<zipcodelist.length;j++)
          for (int k=j+1;k<zipcodelist.length;k++)
            if (k!=j && zipcodelist[k] == zipcodelist[j])
              duplicates=true;
    
        return duplicates;
      }
    
    
      static boolean duplicatesOne(final int[] zipcodelist)
      {
        final int MAXZIP = 99999;
        boolean[] bitmap = new boolean[MAXZIP + 1];
        java.util.Arrays.fill(bitmap, false);
        for (int item : zipcodelist) {
          if (!(bitmap[item] ^= true))
            return true;
        }
        return false;
      }
    
      static boolean duplicatesTwo(final int[] zipcodelist)
      {
        final int MAXZIP = 99999;
    
        BitSet b = new BitSet(MAXZIP + 1);
        b.set(0, MAXZIP, false);
        for (int item : zipcodelist) {
          if (!b.get(item)) {
            b.set(item, true);
          } else
            return true;
        }
        return false;
      }
    
      enum ApproachT { NSQUARED, HASHSET, BITSET};
    
      /**
       * @param args
       */
      public static void main(String[] args)
      {
        ApproachT approach = ApproachT.BITSET;
    
        final int REPS = 100;
        final int MAXZIP = 99999;
    
        int[] sizes = new int[] { 10, 1000, 10000, 100000, 1000000 };
        long[][] times = new long[sizes.length][REPS];
    
        boolean tossme = false;
    
        for (int sizei = 0; sizei < sizes.length; sizei++) {
          System.err.println("Trial for zipcodelist size= "+sizes[sizei]);
          for (int rep = 0; rep < REPS; rep++) {
            int[] zipcodelist = new int[sizes[sizei]];
            for (int i = 0; i < zipcodelist.length; i++) {
              zipcodelist[i] = (int) (Math.random() * (MAXZIP + 1));
            }
            long begin = System.currentTimeMillis();
            switch (approach) {
            case NSQUARED :
              tossme ^= (duplicatesZero(zipcodelist));
              break;
            case HASHSET :
              tossme ^= (duplicatesOne(zipcodelist));
              break;
            case BITSET :
              tossme ^= (duplicatesTwo(zipcodelist));
              break;
    
            }
            long end = System.currentTimeMillis();
            times[sizei][rep] = end - begin;
    
    
          }
          long avg = 0;
          for (int rep = 0; rep < REPS; rep++) {
            avg += times[sizei][rep];
          }
          System.err.println("Size=" + sizes[sizei] + ", avg time = "
                + avg / (double)REPS + "ms");
        }
      }
    
    }
    

    With NSQUARED:

    Trial for size= 10
    Size=10, avg time = 0.0ms
    Trial for size= 1000
    Size=1000, avg time = 0.0ms
    Trial for size= 10000
    Size=10000, avg time = 100.0ms
    Trial for size= 100000
    Size=100000, avg time = 9923.3ms
    

    With HashSet

    Trial for zipcodelist size= 10
    Size=10, avg time = 0.16ms
    Trial for zipcodelist size= 1000
    Size=1000, avg time = 0.15ms
    Trial for zipcodelist size= 10000
    Size=10000, avg time = 0.0ms
    Trial for zipcodelist size= 100000
    Size=100000, avg time = 0.16ms
    Trial for zipcodelist size= 1000000
    Size=1000000, avg time = 0.0ms
    

    With BitSet

    Trial for zipcodelist size= 10
    Size=10, avg time = 0.0ms
    Trial for zipcodelist size= 1000
    Size=1000, avg time = 0.0ms
    Trial for zipcodelist size= 10000
    Size=10000, avg time = 0.0ms
    Trial for zipcodelist size= 100000
    Size=100000, avg time = 0.0ms
    Trial for zipcodelist size= 1000000
    Size=1000000, avg time = 0.0ms
    

    BITSET Wins!

    But only by a hair... .15ms is within the error for currentTimeMillis(), and there are some gaping holes in my benchmark. Note that for any list longer than 100000, you can simply return true because there will be a duplicate. In fact, if the list is anything like random, you can return true WHP for a much shorter list. What's the moral? In the limit, the most efficient implementation is:

     return true;
    

    And you won't be wrong very often.

    0 讨论(0)
  • 2020-11-22 10:02

    How about using this method?

    HashSet<Integer> zipcodeSet = new HashSet<Integer>(Arrays.asList(zipcodeList));
    duplicates = zipcodeSet.size()!=zipcodeList.length;
    
    0 讨论(0)
  • 2020-11-22 10:03

    This program will print all duplicates value from array.

    public static void main(String[] args) {

        int[] array = new int[] { -1, 3, 4, 4,4,3, 9,-1, 5,5,5, 5 };
        
        Arrays.sort(array);
    
     boolean isMatched = false;
     int lstMatch =-1;
          for(int i = 0; i < array.length; i++) {  
              try {
                    if(array[i] == array[i+1]) { 
                        isMatched = true;
                        lstMatch = array[i+1]; 
                    }
                    else if(isMatched) {
                        System.out.println(lstMatch);
                        isMatched = false;
                        lstMatch = -1;
                    }
              }catch(Exception ex) {
                  //TODO NA
              }
    
          }
          if(isMatched) {
              System.out.println(lstMatch);
          }
    
    }
    

    }

    0 讨论(0)
提交回复
热议问题