Usuń duplikaty z macierzy i zapisz w innej [duplikat]

Nov 24 2020

Otrzymałem zadanie utworzenia tablicy bez zduplikowanych wartości z innej istniejącej tablicy. Zrobiłem to, ale chcę wiedzieć, czy istnieje inny lepszy sposób na zrobienie tego.

Przykładowe wejście / wyjście

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

Output: 1, 15, 5, 3

Mój kod

#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;
}

Chcę kilka sugestii.

Z góry dziękuję. :)

Odpowiedzi

1 TobySpeight Nov 24 2020 at 19:55

Jeśli dane wejściowe naprawdę zawierają przecinki między liczbami, będziemy chcieli to uwzględnić tutaj:

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

W każdym razie ważne jest, aby sprawdzić zwracaną wartość z scanf(), w przeciwnym razie moglibyśmy użyć wartości, które nie zostały poprawnie zainicjalizowane.

Prawdopodobnie warto napisać oddzielne funkcje dla wejścia, wyjścia i przetwarzania, a następnie mieć prostą, main()która łączy te trzy razem.

1 Noname Nov 24 2020 at 18:25

Można uniknąć flagi „dup”, zmieniając układ wewnętrznej pętli. Oto kompaktowa wersja, trochę wywrócona na lewą stronę, abyśmy mogli zrobić swoje od p[k++]=razu:

    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;
            }
        }
    }

Dla jasności prawie wolę to jako wewnętrzną pętlę:


     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 
     }

To jest bardziej symetryczne; możesz łatwo porównać dwa warunki wyjścia dla tej wiecznej pętli (brak wyrażenia środkowego).

Ważne jest, aby najpierw sprawdzić, czy josiągnął ARRAY_SIZE, a dopiero potem użyć go w m[j].


W przypadku tablicy takiej jak 120000000...000012myślę, szybsze byłoby wyszukiwanie w nowej, unikalnej tablicy ... ale tak, dlatego sortowanie jest przydatnym pierwszym (i głównym) krokiem.


Pierwsza (kompaktowa) wersja jest nawet błędna . m[j]będzie już niedozwolony dla ostatniego elementu.

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