web-dev-qa-db-fra.com

Java + Count duplique du tableau int sans utiliser aucune collection ni aucun autre tableau intermédiaire

Dans le cadre de la question d’interview Java, j’ai le problème suivant à résoudre . Mais je me demande un peu si je peux l’implémenter sans Collection ou tableau intermédiaire.

Question: - Compter les doublons du tableau int sans utiliser aucune collection ni aucun autre tableau intermédiaire 

Input values:- {7,2,6,1,4,7,4,5,4,7,7,3, 1}  

Output:- Number of duplicates values: 3
         Duplicates values: 7, 4, 1

J'ai implémenté la solution suivante mais je n'en avais pas terminé une. Quelqu'un a une idée? Merci.

public static void duplicate(int numbers[]) {

    for (int i = 0; i < numbers.length; i++) {

        boolean duplicate = false;
        int j = 0;

        while (j < i){

            if ((i != j) && numbers[i] == numbers[j]) {
                duplicate = true;
            }

            j++;
        }

        if (duplicate) {
            System.out.print(numbers[i] + " ");
        }
    }
}
8
Channa

Le moyen le plus simple de résoudre ce problème consiste à trier le tableau en premier, puis à parcourir le tableau en comptant les doublons au fur et à mesure que vous les rencontrez:

int[] numbers = new int[]{7,2,6,1,4,7,4,5,4,7,7,3,1};
int temp = 0;

// I chose to do a bubble sort of the array,
// but you are free to use any method you wish (e.g. Arrays.sort)
System.out.print("Duplicates values: ");
for (int i=0; i < numbers.length; ++i) {
    for (int j=1; j < (numbers.length - i); ++j) {
        if (numbers[j-1] > numbers[j]) {
            temp = numbers[j-1];
            numbers[j-1] = numbers[j];
            numbers[j] = temp;
        }
    }
}


// walk through the sorted array and count duplicates
int numDup = 0, dupCount = 0;
int previous = -1;
for (int i=0; i < numbers.length; ++i) {
    if (numbers[i] == previous) {
        ++numDup;
        if (numDup == 1) {
            ++dupCount;
            if (dupCount == 1) {
                System.out.print(numbers[i]);
            }
            else {
                System.out.print(", " + numbers[i]);
            }
        }
    }
    else {
        previous = numbers[i];
        numDup = 0;
    }
}

System.out.println("\nNumber of duplicates values: " + dupCount);

Sortie:

Duplicates values: 1, 4, 7
Number of duplicates values: 3

Notez que mon ordre de sortie est l'inverse de ce que vous avez, car vous devez lire tout le tableau avant de savoir le nombre total de doublons que vous avez. De plus, je ferai remarquer que le seul état utilisé par cette solution est le tableau d’entrée lui-même, plus quelques variables int ici et là.

Ce code a été testé dans IntelliJ et il fonctionne correctement.

8
Tim Biegeleisen

D'accord pour Tim @ tim-biegeleisen. Juste un changement mineur. Utilisez les tableaux pour trier le tableau.

classe publique DuplicateClass {

public static void main(String[] args) {
    int[] values = { 7, 2, 6, 1, 4, 7, 4, 5, 4, 7, 7, 3, 1 };
    duplicate(values);
}

public static void duplicate(int numbers[]) {
    Arrays.sort(numbers);
    int previous = numbers[0] - 1;
    ;
    int dupCount = 0;

    for (int i = 0; i < numbers.length; ++i) {
        if (numbers[i] == previous) {
            ++dupCount;
        } else {
            previous = numbers[i];
        }
    }
    System.out.println("There were " + dupCount + " duplicates in the array.");
}

}

2
Crazy Developer

Ce sont toutes d'excellentes réponses. Un autre consiste à utiliser un int/double et à définir ses bits lorsque vous rencontrez un nombre. Cela fonctionne si les valeurs du tableau sont inférieures à 32/64 selon le type que vous utilisez. 

Vous trouverez ci-dessous un exemple de la manière dont vous feriez cela avec un entier. 

public class SetThoseBits{

    // 0000 0000 0000 0000 000 0000 0000 0000
    public static int data = 0; 

    public static void main(String [] args){

        // Gurantee that the numbers are less than 32
        int[] values = { 7, 2, 6, 1, 4, 7, 4, 5, 4, 7, 7, 3, 1 };
        duplicates(values);

    }

    public static void duplicates(int [] values){

        for(int i : values){

            if(testBit(i)){
                System.out.println("Duplicate :" + i);
            } else{
                setBit(i);
            }
            //printBits();
        }

        System.out.println("Finished!");
    }

    // Sets the bit at a specific position
    public static void setBit(int index){
        data = data | (1 << index);
    }

    // This function will test the bit at the index of the given integer
    // If it's set, it returns true
    public static boolean testBit(int index){
        return ((data & (1 << index)) != 0);
    }

    public static void printBits(){

        for (int x = 31; x >= 0; x--){
            if(testBit(x)){
                System.out.print("1");
            } else{
                System.out.print("0");
            }
        }
        System.out.println("0");
    }

}

Je pense que les autres réponses sont meilleures compte tenu de votre question ... mais le démontrer comme une alternative montre que vous y réfléchissez de manière dynamique. Si les exigences de la question changeaient un peu, cette réponse serait peut-être plus appropriée. 

De plus, si vous devez seulement garder une trace des doublons compte tenu du plus petit encombrement possible, vous pouvez faire quelque chose de similaire à ce qui précède ou utiliser la classe BitSet de Java pour vous simplifier la vie. 

http://docs.Oracle.com/javase/7/docs/api/Java/util/BitSet.html

Edit: Il est également possible d'avoir des valeurs supérieures à 64 étant donné que vous créez une fonction contenant un tableau d'octets comme la classe BitSet. Pour cette question précise, cela n'est pas utile étant donné la contrainte de ne pas utiliser un tableau ou une collection. 

1
Pumphouse

Je pense que c'est aussi un moyen de le calculer:

public class App {
    public static void main(String[] args) {
        Integer[] intArr = { 7, 2, 6, 1, 4, 7, 4 };
        List<Integer> listInt = Arrays.asList(intArr);

        Map<Integer, Integer> map = new HashMap<>();
        Integer dupCount = 0;
        StringBuilder dupvalues = new StringBuilder();

        for (Integer integer : intArr) {
            int times = Collections.frequency(listInt, integer);
            if (map.containsKey(integer)) {
                dupvalues.append(integer).append(",");
                dupCount++;
            } else
                map.put(integer, times);
        }
        System.out.println("There were " + dupCount + " duplicates in the array. The value are : "+dupvalues);
    }
}
0
user5778069

Il existe une méthode d'utilisation de Math.abs. Vous devriez vérifier si le signe est positif. S'il est positif, faites-le en négatif. Si c'est négatif, alors c'est le nombre dupliqué ou le nombre répété. Exemple: A [] = {1, 1, 2, 3, 2} I = 0; Vérifiez le signe de A [abs (A [0])] qui est A [1]. Un [1] est positif, alors le rendre négatif. Le tableau devient maintenant {1, -1, 2, 3, 2}

i = 1; Vérifiez le signe de A [abs (A [1])] qui est A [1]. Un [1] est négatif, donc A [1] est une répétition . Mettez ensuite tous ces nombres répétés dans une liste et imprimez la taille de la liste.

Le code en python est 

    from astropy.extern.ply.cpp import xrange
def printrepeat(arr):
    print("The repeating elements are: ")
    list =[]
    for i in xrange(0,len(arr)):
        ch = abs(arr[i])

        if arr[ch] > 0:
            arr[ch] = (-1)*arr[ch];

        else: list.append(arr[ch])

    print(len(list))    




# driver code

arr = [1 , 3 , 2 , 2 , 1,3]
printrepeat(arr)            

Solution 2: Prendre 2 pointeurs

class Abc1{
    public static void main(String[] args) {

   int[] a = {1, 1, 2, 3, 2};
   countDuplicates(a);
}

    private static void countDuplicates(int[] a) {
        int c = 0 ;
        for(int  i = 0 ; i < a.length ; i++) {

            for(int j = i+1 ; j < a.length;j++) {
                if(a[i] == a[j]) {c++ ;}
            }//for
        }//for1
        System.out.println("dup => " + c);
    }

}

Solution 3: HashSet

class Abc1{
    public static void main(String[] args) {

  String a = "Gini Gina Protijayi";
   countDuplicates(a);
}

    private static void countDuplicates(String aa) {
        List<Character> list= new ArrayList<>();
       Set<Character> set = new HashSet<>();
       // remove all the whitespaces 
       String a = aa.replaceAll("\\s+","");
       for(  char ch : a.toCharArray()) {

           if(!set.contains(ch)) {
               set.add(ch);
           }//if
           else {if(!list.contains(ch) ) {list.add(ch);}      }
       }//for
       System.out.println("number of duplicate characters in the string =>" + list.size());
       System.out.println(list);
    }

}

Solution: 4 (même concept que la solution 1 mais le code est en Java)

import Java.util.ArrayList;
import Java.util.List;

public class AA {

    public static void main(String[] args) {
         int a[] = {4, 2, 4, 5, 2, 3, 1};
         printRepeat(a);


    }

    private static void printRepeat(int[] a) {
        List<Integer> list = new ArrayList<>();
        for (int i = 0; i < a.length; i++) {
            if( a[Math.abs(a[i])]  > 0) {
                a[Math.abs(a[i])] = (-1)*  a[Math.abs(a[i])] ; 
            }//if
            else {
                System.out.println( "Duplicate numbers => " + Math.abs(a[i])         );
                list.add(Math.abs(a[i]));
                System.out.println("list => " + list);
                System.out.println("list.size() or the count of duplicates => " + list.size());
            }//else

        }//for

    }//print
    }
0
Soudipta Dutta

Conserver une variable supplémentaire pour maintenir le nombre, plus le tri du tableau dans la phase initiale.

public static void main(String[] args) {
        int[] numbers = { 7, 2, 6, 1, 4, 7, 4, 5, 4, 7, 7, 3, 1 };
        Arrays.sort(numbers);
        System.out.println("Sorted Array is :: = " + Arrays.toString(numbers));

        int count = 0;
        int tempCount = 0; // to keep local count of matched numbers
        String duplicates = "";
        for (int i = 1; i < numbers.length; i++) {
            if (numbers[i] == numbers[i - 1]) {
                if ((tempCount == 0)) { // If same number is repeated more than
                                        // two times, like 444, 7777
                    count = count + 1;
                    tempCount = tempCount + 1;
                    duplicates = duplicates.concat(Integer.toString(numbers[i])
                            + ",");
                }
            } else {
                tempCount = 0;
            }
        }

        System.out.println("No of duplicates :: = " + count);
        System.out.println("Duplicate Numbers are :: = " + duplicates);
    }

sortie

Sorted Array is :: = [1, 1, 2, 3, 4, 4, 4, 5, 6, 7, 7, 7, 7]
No of duplicates :: = 3
Duplicate Numbers are :: = 1,4,7,
0
Ankur Singhal

La méthode ci-dessous n'utilise aucune collection, utilisez simplement la méthode Arrays.sort () pour aider à trier les tableaux par ordre croissant, par exemple. Array = [9,3,9,3,9] sera classé dans [3,3,9,9 , 9] .Si vous saisissez [9,9,9,9,9], le résultat attendu est 1, puisque seul le nombre répété est 9. Si vous saisissez [9,3,9,3,9,255,255,1], le résultat attendu est 3 , puisque les nombres répétés sont 3,9,255. Si vous saisissez [7,2,6,1,4,7,4,5,4,7,7,3,1], le résultat attendu est 3, car les nombres répétés sont 1,4,7.

public static int findDuplicateCountsInArray(int[] nums) {
    // Sort the input array into default ascending order
    Arrays.sort(nums);
    int prev = nums[0];
    int count = 0;
    // Recording a number already a repeated one
    // e.g [9,9,9] the 3rd 9 will not increase duplicate count again
    boolean numAlreadyRepeated = false;
    for(int i = 1; i < nums.length; i++) {
        if(prev == nums[i] && !numAlreadyRepeated) {
            count++;
            numAlreadyRepeated = true;
        } else if(prev != nums[i]) {
            prev = nums[i];
            numAlreadyRepeated = false;
        }
    }
    return count;
}
0
Lampard

C’est la solution la plus simple à laquelle je puisse penser. Je viens d'ajouter un compteur supplémentaire pour que les entiers avec deux répétitions ou plus toujours dans le tableau soient ignorés.

static int findNumber(int[] arr) 
{  
    int duplicateCounter = 0;

    System.out.print("Duplicates: ");

    for(int i = 0; i < arr.length; i++)
    {
        boolean duplicate = false;
        int numOfOccurrences = 1;

        for (int j = (i+1); j < arr.length; j++)
        {
            if (arr[i] == arr[j])
            {
                numOfOccurrences++;
                duplicate = true;
            }
        }
        if(numOfOccurrences == 2 && duplicate == true)
        {
            duplicateCounter++;
            System.out.print(arr[i] + " ");
        }
    }

    return duplicateCounter;
}

Mon test: Test

Entrée: 1, 2, 3, 4, 2, 4, 1, 1, 1

Doublons: 2 4 1

Nombre de doublons: 3

0
jaymaytay
    int numbers[]={7,2,6,1,4,7,4,5,4,7,7,3, 1};
    String temp="";
    int count=0;
    Arrays.sort(numbers);

    for (int i = 0; i < numbers.length; i++) {

        boolean duplicate = false;
        for(int j = 0; j < numbers.length; j++) {
            if ((i != j) && numbers[i] == numbers[j]) {
                duplicate = true;
            }
        }

        if (duplicate) {
            if(!temp.contains(""+numbers[i]))
            {
            temp+=numbers[i]+", ";//adding a number if its duplicate
            count++;//counting unique duplicate number
            }
            System.out.print(numbers[i] + " ");
        }
    }
    System.out.println("\nDuplicates are: "+temp+" count: "+count);

Sortie:

 Duplicates are: 1, 4, 7,  count: 3
0
SatyaTNV