-1
\$\begingroup\$

I have been tasked to make an array without duplicated values from another existing array. So I did it, but I want to know is there some other better way to do that.

Example input/output

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

Output: 1, 15, 5, 3

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

I want some suggestions.

Thanks in advance. :)

\$\endgroup\$
4
  • \$\begingroup\$ your algorithm is O(n^2) because of the nested loop. You could try using the qsort() function from the C header stdlib.h to first sort the array, then iterate through the sorted array once to only add the unique elements. This would be O(nlogn) time. Hash sets are even better but I don't know if there's a standard library object for that \$\endgroup\$
    – John K
    Nov 24 '20 at 10:11
  • \$\begingroup\$ @JohnK Thanks for the advice. :) \$\endgroup\$
    – parallela
    Nov 24 '20 at 10:12
  • 2
    \$\begingroup\$ You're supposed to ask about your own code, not someone else's. \$\endgroup\$ Nov 24 '20 at 13:56
  • \$\begingroup\$ One of several things is possible: either you copy-and-pasted the original question (including suggestions from its answer), which makes this off-topic due to authorship; or @parallela is a sock puppet for Lubomir Stankov and you're asking the same question with nearly no modification, which makes it a simple duplicate. Either way, in its current state this needs to be closed. \$\endgroup\$
    – Reinderien
    Nov 24 '20 at 16:33
1
\$\begingroup\$

If the input really does have commas between the numbers, then we'll want to allow for that here:

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

In any case, it's important to check the return value from scanf(), otherwise we could be using values that haven't been properly initialised.

It's probably worth writing separate functions for the input, output and processing, and then have a simple main() that links the three together.

\$\endgroup\$
1
\$\begingroup\$

A flag "dup" can be avoided by rearranging the inner loop. Here is a compact version, somehow a bit inside-out so that we can do our thing p[k++]= right on the spot:

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

For clarity I almost prefer this as the inner loop:


     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 
     }

This is more symmetric; you can easily compare the two exit conditions for this eternal loop (no middle expression).

It is important to first check if j has reached ARRAY_SIZE, and only then use it in m[j].


For an array like 120000000...000012 I think it would be faster to search in the new, unique array...but yes, that is why sorting is a useful first (and main) step.


The first (compact) version is even wrong. m[j] will already be illegal for the last element.

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

\$\endgroup\$
0

Not the answer you're looking for? Browse other questions tagged or ask your own question.