Supprimez les doublons du tableau et enregistrez-le dans un autre [duplicate]

Nov 24 2020

J'ai été chargé de créer un tableau sans valeurs dupliquées à partir d'un autre tableau existant. Alors je l'ai fait, mais je veux savoir s'il existe une autre meilleure façon de le faire.

Exemple d'entrée / sortie

Input: 1, 15, 1, 5, 1, 3

Output: 1, 15, 5, 3

Mon code

#include <stdio.h>

int main(void) {
  const int ARRAY_SIZE = 5;

  int m[ARRAY_SIZE], p[ARRAY_SIZE];


  for(int i = 0; i < ARRAY_SIZE; i++) {
    printf("Enter number: ");
    scanf("%d",&m[i]);
  }
  // k variable is used to be the new indexing of the array p;
  int k = 0;

  // if it has a duplication dup is changed to 1;
  int dup = 0;
  
  // Loops through the array.
  for(int i =0; i < ARRAY_SIZE; i++) {
    for(int j = i +1; j <ARRAY_SIZE ; j++) {
        if(m[i] == m[j]) {
            dup = 1;
            break;
        }
    }
    if(dup != 1) {
      p[k++] = m[i];
    }
    dup = 0;
  }

  printf("The array without repeated values\n");

  for(int i = 0; i < k; i++) {
    printf("%d\n",p[i]);
  }

  return 0;
}

Je veux quelques suggestions.

Merci d'avance. :)

Réponses

1 TobySpeight Nov 24 2020 at 19:55

Si l'entrée contient vraiment des virgules entre les nombres, nous voudrons autoriser cela ici:

scanf("%d",&m[i]);

Dans tous les cas, il est important de vérifier la valeur de retour de scanf(), sinon nous pourrions utiliser des valeurs qui n'ont pas été correctement initialisées.

Cela vaut probablement la peine d'écrire des fonctions séparées pour l'entrée, la sortie et le traitement, puis d'avoir un simple main()qui relie les trois ensemble.

1 Noname Nov 24 2020 at 18:25

Un drapeau "dup" peut être évité en réorganisant la boucle interne. Voici une version compacte, un peu à l'envers pour que nous puissions faire notre truc p[k++]=sur place:

    for (int i = 0; i < ARRAY_SIZE; i++) {

        for (int j = i + 1; m[i] != m[j]; j++) { /*NO! m[i+1] will be illegal */

            if (j == ARRAY_SIZE) {
                p[k++] = m[i];        // copy this one, next "i" please
                break;
            }
        }
    }

Pour plus de clarté, je préfère presque cela comme boucle intérieure:


     for (int j = i + 1;; j++) {

          if (j == ARRAY_SIZE) {
              p[k++] = m[i];        // copy this one, next please
              break;
          }
          if (m[i] == m[j])
              break;               // skip, next 
     }

Ceci est plus symétrique; vous pouvez facilement comparer les deux conditions de sortie pour cette boucle éternelle (pas d'expression du milieu).

Il est important de vérifier d'abord si ja atteint ARRAY_SIZE, et de ne l'utiliser qu'ensuite m[j].


Pour un tableau comme 120000000...000012je pense, il serait plus rapide de rechercher dans le nouveau tableau unique ... mais oui, c'est pourquoi le tri est une première étape (et principale) utile.


La première version (compacte) est même fausse . m[j]sera déjà illégal pour le dernier élément.

for (int j = i + 1; m[i] != m[j];...