2015-03-08 4 views
3

Pour un tableau de taille normale, nous pouvons déterminer s'il contient des doublons en triant ou en utilisant hashset, etc. Mais si nous avons un très grand tableau, disons que la longueur est de 10 milliards, comment Pouvons-nous déterminer s'il contient des doublons? Suivi: si nous savons qu'il doit exister un doublon dans ce grand tableau, comment pourrions-nous déterminer lequel est-il?Déterminez si un très grand tableau contient un doublon

Mon idée utilise le tri, mais je ne sais pas s'il existe une meilleure façon de gérer ces situations.

+0

Vous ne pouvez pas faire mieux que le 'O (n log n)' à partir d'un tri de comparaison, sauf si vous en savez plus sur les données contenues dans le tableau. Vous ne pouvez utiliser le tri de comparaison que si vous avez un moyen de déterminer si les éléments sont en ordre, sinon vous devez comparer chaque élément à chaque autre élément, qui est 'O (n^2)'. – Cirdec

+0

Veuillez spécifier si c'est 10^13 (grand par rapport à la mémoire principale de 2015) ou 10^10 (grand). Quel est le niveau de confiance requis pour que la réponse soit correcte? -> [Filtre Bloom] (http://en.wikipedia.org/wiki/Bloom_filter) (D'un autre côté, si nous parlions de valeurs de 33 bits ...) – greybeard

+0

quel type de données comparez-vous, par exemple, les chaînes de caractères, Nombres? Quelle est la taille de chaque donnée? –

Répondre

2

D'abord, placez vos données dans des compartiments K avec un code comme celui-ci.

files = array of K file handles 
for each d in data { 
    write d to files[hash(d) % K] 
} 
close each file 

Si vous choisissez K assez grand, chaque godet peut facilement entrer dans la RAM. Assurez-vous de choisir une bonne fonction de hachage, sinon les seaux seront déséquilibrés. Le code réel dépendra également du système de stockage que vous utilisez. Par exemple, si vous utilisez un disque dur ordinaire, les recherches coûtent cher et il faut faire attention à ne pas écraser le disque. Une approche possible consisterait à lire autant de données que possible dans la RAM, puis à les parcourir à intervalles réguliers, en les ajoutant à un seul des fichiers de sortie de chaque passage.

Ensuite, il suffit de parcourir chaque compartiment à tour de rôle et de voir s'il contient des doublons. Vous pouvez utiliser n'importe quel algorithme efficace pour détecter les doublons. Une solution alternative consisterait à utiliser un map-reduce framework.

L'étape de carte ressemblera à ceci:

map(value) { 
    emit(key=hash(value), value=value) 
} 

Et la réduction étape ressemblera à ceci:

reduce(key, values) { 
    if there's a duplicate in values { 
     emit the duplicate value. 
    } 
} 

Notez que chaque réducteur ne voir plusieurs valeurs quand il y a un double, ou quand il y a des collisions de hachage. Si vous avez choisi une fonction de hachage raisonnable, celle-ci sera extrêmement rare.

+0

Que diriez-vous d'ajouter un filtre de bloom à la partie de détection de duplicata? Devrait faire un bon raccourci pour dire qu'il n'y en a pas. – Reactormonk

+0

Cela suppose un accès aléatoire assez rapide (qui serait typique de _arrays_ et est plus probable avec des disques durs SSD qu'avec des disques durs, des cassettes, des cartes perforées, des tablettes de pierre ...) – greybeard

+0

@greybeard vous avez raison .. Je vais modifier ma réponse à notez que le code actuel devrait être plus prudent. –