9
votes

Meilleur algorithme pour supprimer des doublons dans le tableau de chaînes

Aujourd'hui à l'école, l'enseignant nous a demandé de mettre en œuvre un algorithme de suppression duplicataire. Ce n'est pas si difficile, et tout le monde est venu avec la solution suivante (pseudocode): xxx

La complexité de calcul de cet algo est n (n-1) / 2 . (Nous sommes au lycée, et nous n'avons pas parlé de Big-O, mais il semble être O (n ^ 2) ). Cette solution semble laid et, bien sûr, lente, alors j'ai essayé de coder quelque chose plus rapide: xxx

de cette façon vs contiendra tous les éléments que nous Je suis déjà passé. Si l'élément V [i] est dans ce tableau, il s'agit d'un duplicata et est retiré. La complexité de calcul de la recherche binaire est journal (n) et pour la boucle principale (deuxième extrait) est n . Par conséquent, l'ensemble cc est n * journal (n) si je ne me trompe pas.

alors j'ai eu une autre idée d'utiliser un arbre binaire, mais je ne peux pas la mettre vers le bas.
Fondamentalement, mes questions sont:

  • est mon calcul CC CCC? (Et, sinon, pourquoi?)
  • Y a-t-il une méthode plus rapide pour cela?

    merci


5 commentaires

Juste pour le disque, c'est bien O (n ^ 2).


Quel est le type de vs , et qu'a ajoute faire exactement?


@ROBIN GREEN: VS est comme V et Ajouter ajoute l'élément spécifié dans la position spécifiée


La complexité (pas le temps / espace mais LOC) de la version rapide dépend si vous êtes autorisé à trier la matrice. Si vous êtes autorisé à changer de commande (c'est-à-dire trier), il devient très simple. Si vous n'êtes pas, vous devez recourir à une astuce: trier les index et utiliser ceux qui recherchent aussi des doublons.


@likao: Voie intelligente, j'aime ça :)


7 Réponses :


0
votes

La recherche binaire ne fonctionnera que si la matrice que vous recherchez est triée. Je suppose que ce n'est pas le cas ici, sinon vous ne seriez pas en boucle sur votre ensemble dans la boucle intérieure de la solution d'origine.


2 commentaires

La recherche binaire est appliquée sur VS, pas V (qui est le tableau d'origine). Je garde le tri, insérant des éléments dans leur bon endroit.


@Blackbear: ah oui, je le lis trop vite; ). Dans ce cas, il me ressemble, en supposant que VS puisse être initialisé pour contenir des valeurs qui ne sont pas en v



6
votes

Vous pouvez souvent utiliser un comprimé espace-temps et investir plus d'espace pour réduire le temps.

Dans ce cas, vous pouvez utiliser un Table de hachage pour déterminer les mots uniques.


3 commentaires

+1 Great, j'ai également pensé à cela aussi, mais je n'ai pas trouvé la fonction de hachage. Pourriez-vous en fournir un, s'il vous plaît?


@Blackbear: De nombreuses langues de programmation ont déjà une telle structure de données qui permet une mappage de clés sur les valeurs.


@Blackbear: Ne vous inquiétez pas de la fonction Hash, la plupart des langues ont une pour les cordes déjà intégrées.



15
votes

La solution la plus simple consistera simplement à trier le tableau (prend le logiciel N (N log n) avec la mise en œuvre standard si vous pouvez les utiliser. Sinon, envisagez de faire une excellente attraction randomisée (code est même sur Wikipedia)).

Ensuite, numérisez-le pendant une heure supplémentaire. Au cours de cette analyse, il élimine les éléments identiques consécutifs.

Si vous voulez le faire dans O (N), vous pouvez également utiliser un hashset avec des éléments que vous avez déjà vus. Juste itérer une fois sur votre tableau, pour chaque élément Vérifiez s'il est dans votre hashset.

Si ce n'est pas là, ajoutez-le. Si c'est là, retirez-le de la matrice.

Remarque, que cela prendra une mémoire supplémentaire et que le hachage aura un facteur constant qui contribue à votre heure d'exécution. Althouht La complexité de temps est meilleure, le temps d'exécution pratique ne sera que plus plus rapide une fois que vous dépassez une taille de montagne de certaines matrices


4 commentaires

Pourriez-vous expliquer plus profondément l'idée de hashset s'il vous plaît?


@Blackbear: C'est la même idée que gumbo a expliqué, un jeu de hachage n'est qu'un nom d'une table de hachage dans laquelle la clé est également la valeur.


Un hashset est une structure de données prenant en charge l'insertion et le test d'adhésion en temps constant. Dans votre cas, vous ne souhaitez certainement pas mettre en œuvre une telle structure de données sur votre propre mais utilisée et existante pour vos langages de programmation. L'ensemble permettra d'ajouter des clés et de vérifier si elles sont déjà contenues dans l'ensemble. Étant donné que les deux opérations sont prises en charge en temps constant et que vous effectuez 1 test d'adhésion (+ 1 insert ou supprimez de votre tableau) pour chaque élément, vous vous retrouvez avec O (N). Notez que cela nécessite de supprimer / supprimer pour se produire en temps constant.


Sauf que les opérations sur un hashset sont des cas moyens O (1). Le pire des cas est O (n) (si vous avez une fonction de hachage de Meshugganah), vous ne pouvez donc garantir que O (n ^ 2) pour l'algorithme entier.



2
votes

Ajouter est O (n) , donc votre calcul de CC est faux. Votre algorithme est O (n ^ 2) .

En outre, comment supprimerait-il être mis en œuvre? Il semble également que ce soit O (n) - l'algorithme initial serait donc o (n ^ 3) .


0 commentaires

0
votes

Si l'ordre de la solution finale est hors de propos, vous pouvez casser la matrice en des matrices plus petites en fonction de la longueur des chaînes, puis de supprimer les doublons de ces tableaux. Exemple: xxx


0 commentaires

0
votes

Il s'agit de l'algorithme le plus court qui a fonctionné lorsque des arrondis et des arachs sont des matrices parallèles et le score le plus élevé est pris.

I := 0;
J := 0;
//iCount being the length of the array

for I := 1 to iCount do
for J := I + 1 to iCount do

   if arrNames[I] = arrNames[J] then
   begin

     if arrScores[I] <= arrScores[J] then
     arrScores[I] := arrScores[J];

   arrScores[J] := arrScores[iCount];
   arrNames[J] := arrNames[iCount];

   arrScores[iCount] := 0;
   arrNames[iCount] := '';

   Dec(iCount);
   end;


0 commentaires

0
votes
def dedup(l):
    ht, et = [(None, None) for _ in range(len(l))], []
    for e in l:
        h, n = hash(e), h % len(ht)
        while True:
            if ht[n][0] is None:
                et.append(e)
                ht[n] = h, len(et) - 1
            if ht[n][0] == h and et[ht[n][1]] == e:
                break
            if (n := n + 1) == len(ht):
                n = 0
    return et

0 commentaires