Home > Software design >  How do I find duplicates of an int in an array in this case?
How do I find duplicates of an int in an array in this case?

Time:10-13

I am working on a school assignment and currently I'm a stuck on a part or it.

The piece of the program that I am showing further down, is supposed to take 7 numbers, check if they are above 0 and below maxValue, then, another function, checkIfContains should check if there are any duplicates in that array and return true or false to the first function, enterRow.

If everything is fine (numbers are within range and no duplicates), then nothing more is to be done by the functions here.. ( I have isolated these two. There are more where these came from, we are supposed to make a lottery game)

What am I doing wrong?

#include <stdio.h>
#include <stdbool.h>
#include <string.h>

void enterRow(int numbers[], int len, int maxValue);
bool checkIfContains(int digit, int arrayToCheck[], int len);


int main(void)
{
    int len = 7;
    int maxValue = 39;
    int numbers[len];
    memset(numbers, 0, sizeof(int) * len);

    enterRow(numbers, len, maxValue);

    return 0;
}

void enterRow(int numbers[], int len, int maxValue)
{
    int flag = 1;
    printf("\nEnter your lotto row (%d values between 1-%d): ", len, maxValue);
    do
    {
        for(int i = 0; i < len; i  )  scanf(" %d", &numbers[i]);

        for (int i = 0; i < len; i  )
        {
            if (numbers[i] < 1 || numbers[i] > maxValue)
            {
                printf("Numbers must be between 1-%d, try again!\n", maxValue);
                break;
            }
            if (checkIfContains(numbers[i], numbers, len) == true)
            {
                printf("Duplicate, try again: ");
                break;
            }
            else
            {
                flag = 2;
            }
        }

    } while (flag == 1);
}
    



bool checkIfContains(int digit, int arrayToCheck[], int len)
{
    for (int i = 1; i < len; i  )
    {
        if (arrayToCheck[i] == digit)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
}

CodePudding user response:

A few issues:

  1. The check function will check the current value against itself, so the array will always have a duplicate
  2. You only want to return false at the end of the loop
  3. There is no return at the end of the function
  4. Your loop was starting with 1 but needs to start with 0

To fix, rather than pass a match value, pass the index of the value.

Here's the refactored code:

#include <stdio.h>
#include <stdbool.h>
#include <string.h>

void enterRow(int numbers[], int len, int maxValue);
bool checkIfContains(int curidx, int arrayToCheck[], int len);

int
main(void)
{
    int len = 7;
    int maxValue = 39;
    int numbers[len];

    memset(numbers, 0, sizeof(int) * len);

    enterRow(numbers, len, maxValue);

    return 0;
}

void
enterRow(int numbers[], int len, int maxValue)
{
    int flag = 1;

    printf("\nEnter your lotto row (%d values between 1-%d): ", len, maxValue);
    do {
        for (int i = 0; i < len; i  )
            scanf(" %d", &numbers[i]);

        for (int i = 0; i < len; i  ) {
            if (numbers[i] < 1 || numbers[i] > maxValue) {
                printf("Numbers must be between 1-%d, try again!\n", maxValue);
                break;
            }
            if (checkIfContains(i, numbers, len) == true) {
                printf("Duplicate, try again: ");
                break;
            }
            else {
                flag = 2;
            }
        }

    } while (flag == 1);
}

bool
checkIfContains(int curidx, int arrayToCheck[], int len)
{

    int digit = arrayToCheck[curidx];

    for (int i = 0; i < len; i  ) {
        // don't check number against itself
        if (i == curidx)
            continue;

        if (arrayToCheck[i] == digit)
            return true;
    }

    return false;
}

CodePudding user response:

The function checkIfContains has two defects.

First of all the loop shall start from the next position of the element that is passed to the function as a value of the parameter digit. It means that the function should be called at least like like

if (checkIfContains(numbers[i], numbers   i   1, len - i - 1 ) == true)

And within the function the for loop shall start from 0

for (int i = 0; i < len; i  )

instead of 1 as in your function

for (int i = 1; i < len; i  )

The second defect is that you shall not return false as soon as unequal element is found in the array.

Using your approach The function can look the following way

bool checkIfContains(int digit, const int arrayToCheck[], int len)
{
    int i = 0;

    while ( i < len && arrayToCheck[i] != digit )   i;

    return i != len;
}

And as I already mentioned the function must be called like

if (checkIfContains(numbers[i], numbers   i   1, len - i - 1 ) == true)

Though your approach too complicated. You could check entered values in the first for loop

for(int i = 0; i < len; i  )
{
    scanf(" %d", &numbers[i]);
    // 1) check whether the value is in the range
    // 2) check whether the value is unique
    //...
}

CodePudding user response:

To check if there are duplicates in an array, the most basic way is to loop through the array using two nested for loops and compare each element with the others, like so:

int array[5] = {5, 7, 6, 3, 5};
int arrayLength = 5;

for(int i = 0; i < arrayLength; i  )
{
    for(int j = i   1; j < arrayLength; j  )
    {
        if(array[i] == array[j]) 
        {
            printf("%d has duplicate\n", array[i]);
        }
    }
}

You can make your code like:

bool hasDuplicate(int array[], int arrayLength)
{
    for(int i = 0; i < arrayLength; i  )
    {
        for(int j = i   1; j < arrayLength; j  )
        {
            if(array[i] == array[j]) 
            {
                return true;
            }
        }
    }
    return false;
}

And you can make enterRow like this:

void enterRow(int numbers[], int len, int maxValue)
{
    printf("\nEnter your lotto row (%d values between 1-%d): ", len, maxValue);

    for(int i = 0; i < len; i  )  
        scanf(" %d", &numbers[i]);

    for(int i = 0; i < len; i  )
    {
        if(numbers[i] > maxValue || numbers[i] < 1)
        {
            printf("Format is not correct.\n");
            while(1);
        }
    }

    if(hasDuplicate(numbers, len) == true)
    {
        printf("The numbers cannot be duplicates.\n");
        while(1);
    }
}
    

This way your code is much cleaner and more readable. Obviously, you should optimize this code to how you want to deal with the error cases and etc.

  • Related