web-dev-qa-db-fra.com

Tableau supprimer les éléments en double

J'ai un tableau non trié, quelle est la meilleure méthode pour supprimer tous les doublons d'un élément s'il est présent?

par exemple:

a[1,5,2,6,8,9,1,1,10,3,2,4,1,3,11,3]

donc après cette opération, le tableau devrait ressembler à

 a[1,5,2,6,8,9,10,3,4,11]
28
mohit

Vérifier chaque élément contre tous les autres éléments

La solution naïve consiste à comparer chaque élément avec tous les autres. C'est un gaspillage et donne un O (n2), même si vous ne faites que "avancer".

Trier puis supprimer les doublons

Une meilleure solution consiste à trier le tableau, puis à vérifier chaque élément à côté de celui-ci pour trouver les doublons. Choisissez un tri efficace et c’est O (n log n).

L'inconvénient de la solution basée sur le tri est que l'ordre n'est pas maintenu. Une étape supplémentaire peut prendre soin de cela cependant. Placez toutes les entrées (dans le tableau unique trié) dans une table de hachage ayant un accès O(1). Puis parcourez le tableau d'origine. Pour chaque élément, vérifiez s'il se trouve dans la table de hachage. Si c'est le cas, ajoutez-le au résultat et supprimez-le de la table de hachage. Vous allez vous retrouver avec un tableau résultant qui a l'ordre de l'original, chaque élément étant dans la même position que sa première occurrence.

Sortes linéaires de nombres entiers

Si vous avez affaire à des entiers d'une plage fixe, vous pouvez faire encore mieux en utilisant une sorte de base. Si vous supposez par exemple que tous les nombres sont compris entre 0 et 1 000 000, vous pouvez allouer un vecteur de bits d'environ 1 000 001. Pour chaque élément du tableau d'origine, vous définissez le bit correspondant en fonction de sa valeur (par exemple, une valeur de 13 entraîne la définition du 14ème bit). Ensuite, parcourez le tableau d'origine, vérifiez s'il se trouve dans le vecteur de bits. Si c'est le cas, ajoutez-le au tableau de résultats et effacez ce bit du vecteur de bits. C'est O(n) et négocie l'espace pour le temps.

Solution de table de hachage

Ce qui nous amène à la meilleure solution: le type est en réalité une distraction, bien que utile. Créez une table de hachage avec un accès O(1). Parcourez la liste originale. S'il ne figure pas déjà dans la table de hachage, ajoutez-le au tableau de résultats et ajoutez-le à la table de hachage. Si c'est dans la table de hachage, ignorez-le.

C'est de loin la meilleure solution. Alors pourquoi le reste? Parce que de tels problèmes consistent à adapter les connaissances que vous avez (ou devriez avoir) à des problèmes et à les affiner en fonction des hypothèses que vous formulez. Développer une solution et comprendre la pensée qui la sous-tend est bien plus utile que de régurgiter une solution.

De plus, les tables de hachage ne sont pas toujours disponibles. Prenez un système embarqué ou quelque chose où l'espace est TRÈS limité. Vous pouvez implémenter un tri rapide dans une poignée d'opcodes, beaucoup moins que ne le pourrait une table de hachage.

72
cletus

Si vous n'avez pas besoin de conserver l'objet d'origine, vous pouvez le boucler et créer un nouveau tableau de valeurs uniques. En C #, utilisez une liste pour accéder aux fonctionnalités requises. Ce n'est pas la solution la plus attrayante ou la plus intelligente, mais cela fonctionne. 

int[] numbers = new int[] {1,2,3,4,5,1,2,2,2,3,4,5,5,5,5,4,3,2,3,4,5};
List<int> unique = new List<int>();

foreach (int i in numbers)
     if (!unique.Contains(i))
          unique.Add(i);

unique.Sort();
numbers = unique.ToArray();
2
WDuffy

Cela peut être fait dans O(n) amorti en utilisant un ensemble basé sur une table de hachage.

Code Psuedo:

s := new HashSet
c := 0
for each el in a
  Add el to s.
    If el was not already in s, move (copy) el c positions left.
    If it was in s, increment c. 
2
Matthew Flaschen
    indexOutput = 1;
    outputArray[0] = arrayInt[0];
    int j;
    for (int i = 1; i < arrayInt.length; i++) {            
        j = 0;
        while ((outputArray[j] != arrayInt[i]) && j < indexOutput) {
            j++;
        }
        if(j == indexOutput){
           outputArray[indexOutput] = arrayInt[i];
           indexOutput++;
        }         
    }
1
dhayyati

Traitez les nombres comme des clés. 

for each elem in array:
if hash(elem) == 1 //duplicate
  ignore it
  next
else
  hash(elem) = 1
  add this to resulting array 
end
Si vous connaissez des données telles que la plage de nombres et si elles sont finies, vous pouvez initialiser ce grand tableau avec celui de ZERO.
array flag[N] //N is the max number in the array
for each elem in input array:
  if flag[elem - 1] == 0
    flag[elem - 1] = 1
    add it to resulatant array
  else
    discard it //duplicate
  end

1
bhups

C’est un segment de code que j’ai créé en C++, essayez-le

#include <iostream>

using namespace std;

int main()
{
   cout << " Delete the duplicate" << endl; 

   int numberOfLoop = 10;
   int loopCount =0;
   int indexOfLargeNumber = 0;
   int largeValue = 0;
   int indexOutput = 1;

   //Array to hold the numbers
   int arrayInt[10] = {};
   int outputArray [10] = {};

   // Loop for reading the numbers from the user input
   while(loopCount < numberOfLoop){       
       cout << "Please enter one Integer number" << endl;
       cin  >> arrayInt[loopCount];
       loopCount = loopCount + 1;
   }



    outputArray[0] = arrayInt[0];
    int j;
    for (int i = 1; i < numberOfLoop; i++) {            
        j = 0;
        while ((outputArray[j] != arrayInt[i]) && j < indexOutput) {
            j++;
        }
        if(j == indexOutput){
           outputArray[indexOutput] = arrayInt[i];
           indexOutput++;
        }         
    }

   cout << "Printing the Non duplicate array"<< endl;

   //Reset the loop count
   loopCount =0;

   while(loopCount < numberOfLoop){ 
       if(outputArray[loopCount] != 0){
        cout <<  outputArray[loopCount] << endl;
    }     

       loopCount = loopCount + 1;
   }   
   return 0;
}
0
Vanji
Time O(n) space O(n) 

#include <iostream>
    #include<limits.h>
    using namespace std;
    void fun(int arr[],int size){

        int count=0;
        int has[100]={0};
        for(int i=0;i<size;i++){
            if(!has[arr[i]]){
               arr[count++]=arr[i];
               has[arr[i]]=1;
            }
        }
     for(int i=0;i<count;i++)
       cout<<arr[i]<<" ";
    }

    int main()
    {
        //cout << "Hello World!" << endl;
        int arr[]={4, 8, 4, 1, 1, 2, 9};
        int size=sizeof(arr)/sizeof(arr[0]);
        fun(arr,size);

        return 0;
    }
0
rjnitt
import Java.util.ArrayList;
import Java.util.Arrays;
import Java.util.Collection;
import Java.util.HashMap;
import Java.util.HashSet;
import Java.util.List;
import Java.util.Set;

public class testing {
    public static void main(String[] args) {
        EligibleOffer efg = new EligibleOffer();
        efg.setCode("1234");
        efg.setName("hey");
        EligibleOffer efg1 = new EligibleOffer();
        efg1.setCode("1234");
        efg1.setName("hey1");
        EligibleOffer efg2 = new EligibleOffer();
        efg2.setCode("1235");
        efg2.setName("hey");
        EligibleOffer efg3 = new EligibleOffer();
        efg3.setCode("1235");
        efg3.setName("hey");
        EligibleOffer[] eligibleOffer = { efg, efg1,efg2 ,efg3};
        removeDupliacte(eligibleOffer);
    }

    public static EligibleOffer[] removeDupliacte(EligibleOffer[] array) {
        List list = Arrays.asList(array);
        List list1 = new ArrayList();
        int len = list.size();
        for (int i = 0; i <= len-1; i++) {
            boolean isDupliacte = false;
            EligibleOffer eOfr = (EligibleOffer) list.get(i);
            String value = eOfr.getCode().concat(eOfr.getName());
            if (list1.isEmpty()) {
                list1.add(list.get(i));
                continue;
            }
            int len1 = list1.size();
            for (int j = 0; j <= len1-1; j++) {
                EligibleOffer eOfr1 = (EligibleOffer) list1.get(j);
                String value1 = eOfr1.getCode().concat(eOfr1.getName());
                if (value.equals(value1)) {
                    isDupliacte = true;
                    break;
                }
                System.out.println(value+"\t"+value1);
            }
            if (!isDupliacte) {
                list1.add(eOfr);
            }
        }
        System.out.println(list1);
        EligibleOffer[] eligibleOffer = new EligibleOffer[list1.size()];
        list1.toArray(eligibleOffer);
        return eligibleOffer;
    }
}
0
Nivi

Utilisez une implémentation Set.
HashSet , TreeSet ou LinkedHashSet si c'est Java.

0
Zaki

Vous pouvez utiliser la syntaxe "in" et "not in" en python, ce qui la rend assez simple. 

La complexité est supérieure à l'approche de hachage, bien qu'un "pas à" équivaut à un parcours linéaire pour déterminer si cette entrée existe ou non.

li = map(int, raw_input().split(","))
a = []
for i in li:
    if i not in a:
        a.append(i)
print a
0
Deepak Pathania
public class RemoveDuplicateArray {
    public static void main(String[] args) {
        int arr[] = new int[] { 1, 2, 3, 4, 5, 6, 7, 2, 3, 4, 9 };
        int size = arr.length;
        for (int i = 0; i < size; i++) {
            for (int j = i+1; j < size; j++) {
                if (arr[i] == arr[j]) {
                    while (j < (size) - 1) {
                        arr[j] = arr[j + 1];
                        j++;
                    }
                    size--;
                }
            }
        }
        for (int i = 0; i < size; i++) {
            System.out.print(arr[i] + "  ");
        }
    }

}

sortie - 1 2 3 4 5 6 7 9 

0
Ved Prakash

Je suis d'accord avec Cletus. Utilisez un QuickSort puis supprimez les doublons

0
Laramie

Ma solution (O(N)) n'utilise pas de mémoire supplémentaire, mais le tableau doit être trié (ma classe utilise l'algorithme de tri par insertion, mais peu importe.):

  public class MyArray
        {
            //data arr
            private int[] _arr;
            //field length of my arr
            private int _leght;
            //counter of duplicate
            private int countOfDup = 0;
            //property length of my arr
            public int Length
            {
                get
                {
                    return _leght;
                }
            }

            //constructor
            public MyArray(int n)
            {
                _arr = new int[n];
                _leght = 0;
            }

            // put element into array
            public void Insert(int value)
            {
                _arr[_leght] = value;
                _leght++;
            }

            //Display array
            public void Display()
            {
                for (int i = 0; i < _leght; i++) Console.Out.Write(_arr[i] + " ");
            }

            //Insertion sort for sorting array
            public void InsertSort()
            {
                int t, j;
                for (int i = 1; i < _leght; i++)
                {
                    t = _arr[i];
                    for (j = i; j > 0; )
                    {
                        if (_arr[j - 1] >= t)
                        {
                            _arr[j] = _arr[j - 1];
                            j--;
                        }
                        else break;
                    }
                    _arr[j] = t;
                }
            }

            private void _markDuplicate()
            {
                //mark duplicate Int32.MinValue
                for (int i = 0; i < _leght - 1; i++)
                {
                    if (_arr[i] == _arr[i + 1])
                    {
                        countOfDup++;
                        _arr[i] = Int32.MinValue;
                    }
                }
            }

            //remove duplicates O(N) ~ O(2N) ~ O(N + N)
            public void RemoveDups()
            {
                _markDuplicate();
                if (countOfDup == 0) return; //no duplicate
                int temp = 0;

                for (int i = 0; i < _leght; i++)
                {
                    // if duplicate remember and continue
                    if (_arr[i] == Int32.MinValue) continue;
                    else //else need move 
                    {
                        if (temp != i) _arr[temp] = _arr[i];
                        temp++;
                    }
                }
                _leght -= countOfDup;
            }
        }

Et principale

static void Main(string[] args)
{
     Random r = new Random(DateTime.Now.Millisecond);
     int i = 11;
     MyArray a = new MyArray(i);
     for (int j = 0; j < i; j++)
     {
        a.Insert(r.Next(i - 1));
     }

     a.Display();
     Console.Out.WriteLine();
     a.InsertSort();
     a.Display();
     Console.Out.WriteLine();
     a.RemoveDups();
     a.Display();

    Console.ReadKey();
}
0
isxaker