Pranav Arora
Pranav Arora

Reputation: 1013

Unique numbers in array

Similar to my previous question, this time I am trying to print the numbers which do not occur twice or more than twice.

Here is my code:

#include <stdio.h>
int main()
{
    int i;
    int a[10]={2,2,2,4,6,6,9,10,10,11};
    for(i=0; i < 10; ++i)
    {
        if(a[i] != a[i+1] && i!=9)
        {    if(i > 0 && a[i] != a[i-1])
             printf("%d ",a[i]);
        }
        if(i==9 && a[i]!=a[i-1])
             printf("%d", a[i]);
    }
    printf("\n");
    return 0;
}

The output comes out to be correct i.e 4,9,11 but I need to consider the final value of i separately. Is there a better way?

Upvotes: 0

Views: 156

Answers (4)

chux
chux

Reputation: 154255

After accept answer

A simplified approach to finding unique values on a sorted array.

#include <stdio.h>

int main() {
  int a[] = { 2, 2, 2, 4, 6, 6, 9, 10, 10, 11 };
  size_t n = sizeof a / sizeof a[0];
  int previous = ~a[0];
  size_t i;
  for (i = 0; i < n; i++) {
    if (a[i] != previous)
      printf("%d ", a[i]);
    previous = a[i];
  }
  printf("\n");
  return 0;
}

Upvotes: 0

Khaled Hawas
Khaled Hawas

Reputation: 81

Note that logical operators have precedence, and upon equal precedence, as in your if statements, they are evaluated left to right. so

if(a[i] != a[i+1] && i!=9)

will evaluate the a[10] before i!=9, leading to out of bound read. If you change that to

if(i!=9 && a[i] != a[i+1])

the problem wont happen, as i!=9 is evaluated before, and since it will be false, the rest is known to be false and not evaluated, no out of bound read.

Better yet, loop on i=0; i<9 and move the second if outside the loop, eliminating the need for the check i!=9 entirely.

Moreover, you code will fail for the array {2,3,.....}, it will not print the first element as it should.

Here is a better version of your code

#include <stdio.h>
int main()
{
    int i;
    int a[10]={2,2,2,4,6,6,9,10,10,11};
    for(i=0; i < 9; ++i)
    {
        if(a[i] != a[i+1])
        {    
            if(i == 0 || a[i] != a[i-1])
                printf("%d ",a[i]);
        }
    }
    if(a[8] != a[9])
        printf("%d", a[9]);
    printf("\n");
    return 0;
}

Note that after the loop, we simply use the proper subscripts. The is more efficient because adding ifs to check for the last element will evaluate those ifs on every iteration, while now it is evaluated only once.

Hope that helps

Upvotes: 2

Haris
Haris

Reputation: 12272

you just have to check that in the for loop the value of i does not go out of array bound

i think this should work

int main()
{
    int i;
    int a[10]={2,2,2,4,6,6,9,10,10,11};
    for(i=0; i < 10; ++i)
    {
        if(a[i] != a[(i+1)%10])
        {    if(i > 0 && a[i] != a[i-1])
                 printf("%d ",a[i]);
        }
    }
    printf("\n");
    return 0;
}

Upvotes: 0

Loocid
Loocid

Reputation: 6451

You could always use a nested for loop to check the values. This way would also work with an unsorted list.

int i;
int j;
int match; 
for (i = 0; i < 10; i++)
{
    match = 0;

    for(j = 0; j < 10; j++)
    {
        if (a[i] == a[j] && i!=j)
            match = 1;
            break;
    }
    if (match == 0)
        printf("%d",a[i]);
}

This code will check each value against all other values and print the numbers that are only found in the list once as per your example.

Upvotes: 1

Related Questions