J'ai récemment vu ce code Javascript sur StackOverflow pour fusionner deux tableaux et supprimer les doublons:
Array.prototype.unique = function() {
var a = this.concat();
for(var i=0; i<a.length; ++i) {
for(var j=i+1; j<a.length; ++j) {
if(a[i] === a[j])
a.splice(j--, 1);
}
}
return a;
};
var array1 = ["Vijendra","Singh"];
var array2 = ["Singh", "Shakya"];
var array3 = array1.concat(array2).unique();
Bien que ce code fonctionne, il est horriblement inefficace ( O(n^2)
). Votre défi est de créer un algorithme avec moins de complexité.
Le critère gagnant est la solution la moins complexe , mais les liens seront rompus par la plus courte longueur de caractères.
Prérequis :
Empaquetez tout votre code ensemble dans une fonction qui répond aux exigences suivantes de «correction»:
- Entrée: deux tableaux
- Sortie: un tableau
- Fusionne les éléments des deux tableaux ensemble - Tout élément dans l'un ou l'autre tableau d'entrée doit être dans le tableau en sortie.
- Le tableau en sortie ne doit pas avoir de doublons.
- L'ordre n'a pas d'importance (contrairement à l'original)
- N'importe quelle langue compte
- N'utilisez pas les fonctions de tableau de la bibliothèque standard pour détecter l'unicité ou fusionner des ensembles / tableaux (bien que d'autres choses de la bibliothèque standard soient correctes). Permettez-moi de faire la distinction que la concaténation de tableaux est correcte, mais les fonctions qui font déjà tout ce qui précède ne le sont pas.
[1, 2, 2, 3]
et le[2, 3, 4]
retour devraient -ils[1, 2, 2, 3, 4]
ou[1, 2, 3, 4]
?Réponses:
Perl
27 personnages
Simple Perl Hack
Je suis sûr que quelqu'un pourrait aller seul. Et donc (Merci Dom Hastings)
la source
sub x{$_{$_}++for@_;keys%_}
(au cas où il s'agirait d'une égalité!) Et l'utiliser comme:z((1,2,3,4),(2,3,4,5,6))
JavaScript O (N)
13112411692 (86?)Version golfée:
Version golfée lisible par l'homme:
Je pourrais utiliser
concat
comme ça et le faire en 86 caractères:Mais je ne sais pas s'il est toujours O (N) basé sur ce JsPerf: http://jsperf.com/unique-array-merging-concat-vs-looping car la version concat est légèrement plus rapide avec des tableaux plus petits mais plus lente avec des baies plus grandes (Chrome 31 OSX).
En pratique, faites cela (le golf regorge de mauvaises pratiques):
Je ne suis pas doué pour la complexité informatique, mais je pense que c'est
O(N)
. J'adorerais si quelqu'un pouvait clarifier.Edit: Voici une version qui prend n'importe quel nombre de tableaux et les fusionne.
la source
O(N)
.O(A*B)
( ne pas utiliserN
car c'est déroutant). Ce serait que si chaque tableau d'entrée (tousA
) avait la même quantité d'éléments (B
) qu'elle l'est réellementO(SUM(B) FOR ALL A)
, ce qui peut être réécrit commeO(N)
lors de la définitionN
du nombre d'éléments de toutes les entrées du tableau.Python 2.7, 38 caractères
Doit être O (N) en supposant une bonne fonction de hachage.
L'
set
implémentation de 8 caractères de Wasi est meilleure, si vous ne pensez pas qu'elle viole les règles.la source
PHP,
69/4268/41 caractèresLa déclaration de fonction comprend 68 caractères:
La déclaration de fonction ne comprend pas 41 caractères:
la source
Aller simple en Ruby
Pour respecter les règles décrites ci-dessus, j'utiliserais une stratégie similaire à la solution JavaScript et utiliserais un hachage comme intermédiaire.
Ce sont essentiellement les étapes que je traverse dans la ligne ci-dessus.
merged_arr
qui contiendra le résultatObject#tap
pour remplir le hachage (référencé commehash
dans letap
bloc) et le renvoyer pour le chaînage de méthode ultérieurarr1
etarr2
en une seule matrice non traitéeel
dans le tableau chaînés, mettre la valeurel
enhash[el]
si aucune valeurhash[el]
existe actuellement. La mémorisation ici (hash[el] ||= el
) est ce qui garantit l'unicité des éléments.Cela devrait fonctionner dans
O(n)
temps. Veuillez me faire savoir si j'ai fait des déclarations inexactes ou si je peux améliorer la réponse ci-dessus pour des raisons d'efficacité ou de lisibilité.Améliorations possibles
L'utilisation de la mémorisation n'est probablement pas nécessaire étant donné que les clés du hachage seront uniques et que les valeurs ne sont pas pertinentes, donc cela suffit:
J'adore vraiment
Object#tap
, mais nous pouvons obtenir le même résultat en utilisantEnumerable#reduce
:Vous pourriez même utiliser
Enumberable#map
:Comment je le ferais dans la pratique
Cela dit, si on me demandait de fusionner deux tableaux
arr1
etarr2
que le résultatmerged_arr
ait des éléments uniques et puisse utiliser n'importe quelle méthode Ruby à ma disposition, j'utiliserais simplement l'opérateur union défini qui est destiné à résoudre ce problème exact:Un coup d'œil rapide à la source de
Array#|
, cependant, semble confirmer que l'utilisation d'un hachage comme intermédiaire semble être la solution acceptable pour effectuer une fusion unique entre 2 tableaux.la source
Une fonction qui prendrait n tableaux pourrait être la suivante:
Golfé, je pense que cela devrait fonctionner (117 caractères)
Mise à jour Si vous souhaitez conserver le type d'origine, vous pouvez
ou golf 149:
Cela peut encore jeter des doutes, si vous voulez faire la distinction
123
et'123'
cela ne fonctionnera pas.la source
O(N)
)?m([1,2,3,4,5],[2,3,4,5,6],[2,3,4,5,6,7])
devient["1", "2", "3", "4", "5", "6", "7"]
python, 46
Ou, en utilisant simplement l'opération set
python, 8
la source
Perl
23 octets, si l'on ne compte que le bloc de code à l'intérieur du sous-programme. Peut être 21, si l'écrasement des valeurs globales est autorisé (il serait supprimé
my
du code). Il renvoie les éléments dans un ordre aléatoire, car l'ordre n'a pas d'importance. En ce qui concerne la complexité, en moyenne c'est O (N) (dépend du nombre de collisions de hachage, mais elles sont plutôt rares - dans le pire des cas, cela peut être O (N 2 ) (mais cela ne devrait pas se produire, car Perl peut détecter les hachages pathologiques , et modifie la valeur de la fonction de hachage lorsqu'il détecte un tel comportement)).Sortie (montrant également le caractère aléatoire):
la source
Fortran:
282252233213Version golfée:
Ce qui non seulement semble infiniment meilleur, mais se compilera en fait (une ligne trop longue dans sa forme jouée) avec la forme lisible par l'homme:
Cela devrait être
O(n)
comme je copiea
dansc
puis vérifie chacunb
contre toutc
. La dernière étape consiste à éliminer les déchets quic
contiendront car ils ne sont pas initialisés.la source
Mathematica 10 caractères
Exemple:
Mathematica2 43 caractères
la source
Tally[Join[a, b]][[;; , 1]]
serait aussi de la triche ;-) BTW, vous pouvez enregistrer des caractères en utilisant des variables à une seule lettre.Javascript 86
Version golfée:
Version lisible:
la source
m([1,0,0,0,0],[0,1,0])
revient[1]
.h[v]=v
parh[v]=1
.JavaScript 60
J'utilise le générateur ES6.
Les éléments suivants peuvent être testés à l'aide du Traceur REPL de Google .
la source
Si vous recherchez une implémentation basée sur JavaScript qui s'appuie sur les objets sous-jacents derrière le framework pour être efficace, j'aurais juste utilisé Set. Habituellement, dans une implémentation, l'objet Set gère intrinsèquement des objets uniques lors de l'insertion avec une sorte d'indexation de recherche binaire. Je sais qu'en Java c'est un
log(n)
recherche, utilisant une recherche binaire basée sur le fait qu'aucun ensemble ne peut contenir un seul objet plus d'une fois.Bien que je ne sache pas si cela est également vrai pour Javascript, quelque chose d'aussi simple que l'extrait suivant peut suffire pour une
n*log(n)
implémentation:JavaScript , 61 octets
Essayez-le en ligne!
Si l'extrait ci-dessus utilise
a = [1,2,3]
etb = [1,2,3,4,5,6]
puiss=[1,2,3,4,5,6]
.Si vous connaissez la complexité de la
Set.add(Object)
fonction en JavaScript, faites le moi savoir, la complexité de ceci estn + n * f(O)
oùf(O)
est la complexité des.add(O)
.la source
APL (Dyalog Unicode) , O (N), 28 octets
Fonction infixe tacite anonyme.
Essayez-le en ligne!
,
concaténer les arguments; SUR)(
…)
Appliquer la fonction tacite anonyme suivante à ce sujet; O (1)⍳⍨
indices selfie (indices de première occurrence de chaque élément dans l'ensemble du tableau); SUR)=
comparer élément par élément à; SUR):⍳∘≢
indices de la longueur du tableau; SUR)(/⍨)
utilisez-le pour filtrer; SUR):⊢
l'argument non modifié; O (1)O (N + 1 + N + N + N + N + 1) = O (N)
la source
JavaScript, 131 caractères
la source
PHP environ 28 caractères [en omettant les exemples de variables de tableau et la variable de résultat].
$ array1 = array (1, 2, 3); $ array2 = tableau (3, 4, 5);
$ result = array_merge ($ array1, $ array2);
la source