2012-05-26 4 views
7

Mi sono imbattuto in un post How to find a duplicate element in an array of shuffled consecutive integers? ma in seguito mi sono reso conto che questo non funziona per molti input.L'utilizzo dell'operatore XOR per la ricerca di elementi duplicati in un array ha esito negativo in molti casi

Per esempio:
arr[] = {601,602,603,604,605,605,606,607}

#include <stdio.h> 
int main() 
{ 
int arr[] = {2,3,4,5,5,7}; 
int i, dupe = 0; 
for (i = 0; i < 6; i++) { 
    dupe = dupe^a[i]^i; 
} 
printf ("%d\n", dupe); 
return 0; 
} 

Come posso modificare il codice in modo che l'elemento duplicato può essere trovato per tutti i casi?

+0

Mi sono imbattuto in un post che parla di compensazione che non riesco a capire http://stackoverflow.com/questions/8018086/xor-to-find-duplicates-in-an-array Qualcuno può suggerire qualcosa .. ?? – Snehasish

risposta

16

Da domanda iniziale:

Supponiamo di avere una matrice di 1001 interi. Gli interi sono in ordine casuale, ma sai che ognuno degli interi è compreso tra 1 e 1000 (inclusi). Inoltre, ogni numero appare solo una volta nell'array, ad eccezione di un numero, che si verifica due volte.

Si dice in sostanza, che l'algoritmo funziona solo quando si dispone di numeri interi consecutivi, iniziando con 1, per finire con alcuni N.

Se si desidera modificarlo per caso più generale, si deve fare Seguente:

Trova minimo e massimo nell'array. Quindi calcolare l'output previsto (xo tutti gli interi tra minimo e massimo). Quindi calcola xor di tutti gli elementi nella matrice. Quindi segui queste due cose e ottieni un risultato.

+1

Considera arr [] = {2, 3, 5, 5, 7}, quindi min = 2 e max = 7 Output previsto = 2^3^4^5^6^7 = 1 XOR di tutti gli elementi nell'array = 2^3^5^5^7 = 6 XOR di 1 e 6 = 1^6 = 7 !!!!! che non è la risposta richiesta !!!!! – Snehasish

+2

{2, 3, 5, 5, 7} non è un array di elementi consecutivi. Consecutivi significa numeri che differiscono di uno, quindi se uno è duplicato allora un buon input è per expample {2, 3, 3, 4, 5, 6, 7}. Nel tuo caso generale, non esiste una soluzione semplice. O hai bisogno della randomizzazione (tabelle hash) o dell'ordinamento per ottenere la risposta. – usamec

1

Ecco il codice mostrato nella domanda originale, che è diverso dalla vostra implementazione. È stato modificato in modo da utilizzare una variabile locale invece che l'ultimo membro della matrice, che fa la differenza:

for (int i = 1; i < 1001; i++) 
{ 
    array[i] = array[i]^array[i-1]^i; 
} 

printf("Answer : %d\n", array[1000]); 
+0

Funziona per il caso indicato in questa domanda ... ma per i casi di test come {1, 2, 10, 11, 5, 6, 8, 5} e {601.602.603,604,605,605,606,607} dà risultati strani !!!! – Snehasish

7

Un'istruzione XOR ha la proprietà che 'a' XOR 'a' sarà sempre 0, cioè si annulla, quindi, se si sa che l'elenco ha solo un duplicato e che l'intervallo è da x a y , 601 a 607 nel tuo caso, è possibile mantenere l'xor di tutti gli elementi da x a y in una variabile, e quindi xor questa variabile con tutti gli elementi che hai nell'array. Dal momento che ci sarà un solo elemento che verrà duplicato, non verrà annullato a causa dell'operazione xor e questa sarà la tua risposta.

void main() 
{ 
    int a[8]={601,602,603,604,605,605,606,607}; 
    int k,i,j=601; 

    for(i=602;i<=607;i++) 
    { 
     j=j^i; 
    } 

    for(k=0;k<8;k++) 
    { 
     j=j^a[k]; 
    } 

    printf("%d",j); 
} 

Questo codice fornirà l'output 605, come desiderato!

+1

Funziona solo quando sono presenti tutti gli elementi tra x e y. Considerate il caso arr [] = {601, 602, 603, 603, 604, 606} L'esecuzione di esso darà un'uscita strana !!!! – Snehasish

+1

ovviamente, e che ho chiarito nella mia risposta stessa! L'operatore XOR ha le sue funzionalità, non puoi farlo funzionare secondo i tuoi desideri! – Ashwyn

+0

Nella migliore delle ipotesi, devi conoscere gli elementi che sono presenti nell'array, (duplicati o meno) e xor con tutti quegli elementi, ad esempio, all'inizio, prendi int i = 601^602^603^603^604^606, ora xor questo con gli elementi che si dice che la matrice contenga (non si sa ancora quale di essi sia duplicato), cioè i^601^602^603^604^606. L'output deve essere 603! – Ashwyn

1
//There i have created the program to find out the duplicate element in array. Please edit if there are required some changes. 
int main() 
{ 
    int arr[] = {601,602,603,604,605,605,606,607}; 
    //int arr[] = {601,601,604,602,605,606,607}; 
    int n= sizeof(arr)/sizeof(arr[0]); 

    for (int i = 0; i < n; i++) 
    { 
     for (int j = i+1; j < n; j++) 
     { 
      int res = arr[i]^arr[j]; 

      if (res == 0) 
      { 
       std::cout<< "Repeated Element in array = "<<arr[i]<<std::endl; 
      } 
     } 
    } 
    return 0; 
} 

// oppure è possibile utilizzare HashTable e funzione di hash quando si entra lo stesso
valore nella tabella di hash che il tempo si può fare se il suo conteggio maggiore di
un valore in particolare indice di HashTable poi si posso dire che ci sono valori ripetuti nell'array.