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]
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".
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.
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.
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.
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();
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.
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++;
}
}
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
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;
}
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;
}
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;
}
}
Utilisez une implémentation Set.
HashSet , TreeSet ou LinkedHashSet si c'est Java.
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
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
Je suis d'accord avec Cletus. Utilisez un QuickSort puis supprimez les doublons
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();
}