Home > Software engineering >  How to check if an element of an array has already been inserted in that array in a "fashionabl
How to check if an element of an array has already been inserted in that array in a "fashionabl

Time:01-10

Context: An exercise asks me to:

  • Create an array of 20 elements;
  • Insert manually 20 numbers, ranging from 10 to 100 (these included), in said array;
  • If the inserted number (example: x) is not 10 <= x <= 100, print that it is not a valid number and prompt the user to reinsert a - valid - number;
  • Print the - valid - inserted number if it has been inserted for the first time (that is if the inserted number is not already present as an element of the array). If the number has been inserted already, do not consider it as one of the 'to be inserted' 20 numbers.

Problem: The issue is that, as you may notice watching the code, it is incredibly unoptimized as in "I couldn't think of a better way to solve this problem, but I do know that there must be an overall better way of doing this". Specifically though, I wasn't able to design a better way to check if the newly inserted number was already inserted before printing it (hence my question).

I have written the following code in which I think I have tackled all of the given tasks.

//Esercizio 6.15  ||| Pag. 277

#include <stdio.h>
#define SIZE 20

int main()
{
    int a[SIZE];
    int nums_left = 20;

    for_cycle:
    for(int i=0; i<SIZE;   i){
        printf("Please insert %d numbers (whole)\n", nums_left);
        scanf("%d", &a[i]);

        //Managing Errors
        if(a[i]<10 || a[i]>100){
            printf("You have inserted a non valid value!\n");
            goto for_cycle;     //heresy! I know
        }

        //Effective execution of the printing  |  The Issue
        if(a[i]!=(a[i-1])){
            if(a[i]!=a[i-2]){
            if(a[i]!=a[i-3]){
            if(a[i]!=a[i-4]){
            if(a[i]!=a[i-5]){
            if(a[i]!=a[i-6]){
            if(a[i]!=a[i-7]){
            if(a[i]!=a[i-8]){
            if(a[i]!=a[i-9]){
            if(a[i]!=a[i-10]){
            if(a[i]!=a[i-11]){
            if(a[i]!=a[i-12]){
            if(a[i]!=a[i-13]){
            if(a[i]!=a[i-14]){
            if(a[i]!=a[i-15]){
            if(a[i]!=a[i-16]){
            if(a[i]!=a[i-17]){
            if(a[i]!=a[i-18]){
            if(a[i]!=a[i-19]){
            if(a[i]!=a[i-20]){
                printf("You have inserted: %d\n", a[i]);
            }}}}}}}}}}}}}}}}}}}

            //Updates of the variable 'numbers left to insert' accordingly
            nums_left--;

        }else{i--;}         //decrements the counter
    }
    return 0;
}

CodePudding user response:

There are two main alternatives for tracking and testing which valid numbers have already been added:

  • search the array itself
  • maintain and use an external data structure for tracking the stored values

You have implemented a slightly buggy and inelegant form of the first. Another answer demonstrates a correct and more elegant variation on this theme.

In the speed for space tradeoff category, however, there are solutions of the second type. You might, for example, use a binary search tree to record the values added so far, and then search that instead of the main array. For so few total values, however, and such a small range of valid ones, a pretty good alternative would be to maintain a simple lookup table of which values had been recorded so far. For example:

#include <stdio.h>

#define SIZE 20
#define MIN_VALID 10
#define MAX_VALID 100

int main(void) {
    int a[SIZE];
    _Bool seen[MAX_VALID   1] = { 0 };

    for (int next_position = 0; next_position < SIZE; ) {
        printf("Please insert %d numbers (whole)\n", SIZE - next_position);
        scanf("%d", &a[next_position]);

        if (a[next_position] < MIN_VALID || a[next_position] > MAX_VALID){
            printf("%d is not a valid value!\n", a[next_position]);
        } else if (seen[a[next_position]]) {
            printf("You already inserted %d!\n", a[next_position]);
        } else {
            printf("You have inserted: %d\n", a[next_position]);
            seen[a[next_position]] = 1;
            next_position  = 1;
        }
    }

    return 0;
}

CodePudding user response:

Just use an inner loop (goto deleted):

#include <stdio.h>
#define SIZE 20

int main()
{
    int a[SIZE] = {0};

    for (int i = 0; i < SIZE;)
    {
        printf("Please insert %d numbers (whole)\n", SIZE - i);
        scanf("%d", &a[i]);

        // Managing Errors
        if (a[i] < 10 || a[i] > 100)
        {
            printf("You have inserted a non valid value!\n");
            continue;
        }
        int j;
        // Do not allow repeated numbers
        for (j = 0; j < i; j  )
        {
            if (a[j] == a[i])
            {
                printf("%d was already inserted at position %d\n", a[i], j);
                break;
            }
        }
        if (j == i)
        {
            printf("You have inserted: %d\n", a[i]);
            i  ;
        }
    }
    return 0;
}

CodePudding user response:

Given that the range of numbers is limited to 91 options, it is reasonable to create an array of bool initialized to false to store flags to determine if a number has been entered.

On each number being added, if the corresponding flag is false, accept the number and change that flag to true.

A simple implementation of this idea might look like:

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

#define N 20
#define LOWER 10
#define UPPER 100

int main(void) {
    bool flags[UPPER - LOWER   1] = { false };
    int input_numbers[N];

    for (size_t i = 0; i < N; i  ) {
        while (true) {
            int n;

            if (scanf("%d", &n) != 1) {
                printf("Please enter a number.\n");
                while (getchar() != '\n');
                continue;
            }
       
            if (n >= LOWER && n <= UPPER && !flags[n-LOWER]) {
                input_numbers[i] = n;
                flags[n-LOWER] = true;
                break;
            }
            printf("Invalid input.\n");
        }
    }

    return 0;
}
  • Related