1

Currently I am trying to solve this task: Two arrays of five integers each are given. Find the lowest number in the first array that is not in the second array.

It seems to me that if the user enters such integers in the first array:

0 1 2 3 4 

And the integers of the second array:

0 2 3 4 5

The lowest integer, according to the condition of the task, will be 1, because it is not in the second array. So here is my code:

#include <stdio.h>
#include <locale.h>

int main() {
    setlocale(LC_ALL, "Rus");
    int arr1[5]; //initialize arrays
    int arr2[5];
    printf("Enter integers\n");

    for (int i = 0; i < 5; i++) {
        int element;
        scanf_s("%d", &element); 
        arr1[i] = element;
    }

    printf("Enter integers\n");

    for (int i = 0; i < 5; i++) {
        int element;
        scanf_s("%d", &element); 
        arr2[i] = element;
    }

    int min1 = arr1[0];
    int min2 = arr2[0];

    for (int i = 0; i < 5; i++) { // algorithm for finding the minimum number of an array 1
        if (min1 > arr1[i]) {
            min1 = arr1[i];
        }

        if (min2 > arr2[i]) {
            min2 = arr2[i];
        }
    }
}

Well, the code is very clear, but here's how to make this check, if the first array input 0 1 2 3 4 and the second 0 2 3 4 5 then how to remove this zero.

3
  • Find the lowest value in the first array. Search for it in the second array - if not found done. If found repeat with next lowest value in the first array. Tip: write functions for each step. Commented Oct 18, 2022 at 22:55
  • Please edit your question title to describe the problem you're having or question you're asking. A task on C language is meaningless. It's clear it's a task because you're writing the code, and the C language is indicated by the tag. Your title should be clear and descriptive enough to have meaning to a future site user who is skimming a list of search results trying to find a solution to a problem. Your current title is nothing but meaningless noise. For more information, see How to Ask. Commented Oct 18, 2022 at 23:30
  • " tried lots of things, my head hurts" User input can be deceptively difficult. Hard code array values to start, and once you think your logic is working, you can tackle user input afterwards. You should always check the result of scanf to make sure you read the number of values you expected. Commented Oct 18, 2022 at 23:38

3 Answers 3

1

There are some issues ...

  1. We don't care about the min value for arr2--only for arr1
  2. We must scan all arr2 values for a match to the current/candidate value of arr1
  3. There are some special cases we must handle

Normally, if we're just looking for the min value in arr1 (e.g. arr2 is not a factor), we can do [as you've done]:

int min1 = arr1[0];

And, we could start indexing into arr1 from 1 in the for loop.

But, this fails if:

  1. arr1[0] is the min value in arr1 and that value is in arr2
  2. arr1 and arr2 have identical values [even if they are in a different order].

So, we need an extra [boolean] value to denote whether the min1 value is valid. And, we must start indexing in the for loop from 0.

Here is the refactored code. It is annotated:

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <locale.h>

#define A1MAX   5
#define A2MAX   5

int
main(void)
{
    setlocale(LC_ALL, "Rus");

    // define arrays
    int arr1[A1MAX];
    int arr2[A2MAX];

    printf("Enter integers\n");
    for (int i = 0; i < A1MAX; i++) {
        if (scanf("%d", &arr1[i]) != 1) {
            printf("missing arr1[%d] -- %s\n",i,strerror(errno));
            return 2;
        }
    }

    printf("Enter integers\n");
    for (int i = 0; i < A2MAX; i++) {
        if (scanf("%d", &arr2[i]) != 1) {
            printf("missing arr2[%d] -- %s\n",i,strerror(errno));
            return 3;
        }
    }

    int nomin = 1;
    int min1 = arr1[0];

    // check all values in arr1
    for (int i = 0; i < A1MAX; i++) {
        // current value we're going to test
        int val = arr1[i];

        // check value if it's a _new_ minimum or we do _not_ yet have a minimum
        if ((val < min1) || nomin) {
            // scan all elements of arr2, looking for a match to the current
            // arr1 value
            int match = 0;
            for (int j = 0; j < A2MAX; j++) {
                match = (val == arr2[j]);
                if (match)
                    break;
            }

            // if the current value is _not_ in arr2, we have a new minimum
            if (! match) {
                min1 = val;
                nomin = 0;
            }
        }
    }

    if (nomin)
        printf("there are no elements in arr1 that are not in arr2\n");
    else
        printf("the minimum element in arr1 not in arr2 is: %d\n",min1);

    return nomin;
}
Sign up to request clarification or add additional context in comments.

Comments

1

Things get complicated with code tries to maintain multiple indexes into multiple arrays... Things are simplified if you re-use code and break out functions (that can test user input, too)...

#include <stdio.h>

void fill( int arr[], size_t sz ) { // Get user input (with checking)
    printf("Enter integers\n");
    for( size_t i = 0; i < sz; i++ )
        if( scanf( "%d", &arr[i] ) != 1 ) {
            fprintf( stderr, "scanf failure\n" );
            exit(1);
        }
}

// Search for a value in an array. Return index if found, or size if not found
size_t hunt( int val, int arr[], size_t sz ) {
    for( size_t i = 0; i < sz; i++ )
        if( val == arr[i] )
            return i;
    return sz;
}

int main() {
#if 0 // Normal with user entry
    int arr1[5], arr2[5];
    size_t a1sz = sizeof arr1/sizeof arr1[0];
    size_t a2sz = sizeof arr2/sizeof arr2[0];

    fill( arr1, a1sz );
    fill( arr2, a2sz );
#else // less tedious with compile time init of data
    int arr1[] = { 0, 1, 2, 3, 4 };
    int arr2[] = { 0, 2, 3, 4, 5 };
    size_t a1sz = sizeof arr1/sizeof arr1[0];
    size_t a2sz = sizeof arr2/sizeof arr2[0];
#endif

    size_t gotOne = 0;
    for( size_t i = 0; i < a1sz; i++ ) {
        // don't bother testing values if got a candidate and value is larger
        if( gotOne && arr1[i] >= arr1[ gotOne ] ) continue;

        // following is TRUE when not found...
        if( hunt( arr1[i], arr2, a2sz ) == a2sz )
            gotOne = i + 1;
    }

    if( gotOne )
        printf( "Smallest in arr1 not in arr2 = %u\n", arr1[ gotOne - 1 ] );
    else
        puts( "No such value matching criteria" );

    return 0;
}
Smallest in arr1 not in arr2 = 1

Comments

1

Algorithm

The naive approach to this, and one that works very well for small datasets, is to nest a couple of loops. This approach grows in time complexity very fast. O(m*n) where m is the length of the first array and n is the length of the second array.

Fortunately, we can approach this in a way that does not involve nested loops. This assumes both arrays contain only unique values. If they have duplicates, removing those duplicates would be a necessary step before the below can be performed.

Let's start with a couple of simple arrays:

int foo[] = {1, 4, 7, 9, 2};
int bar[] = {4, 1, 6, 7, 3};

Let's combine them into another array. This is a linear operation.

{1, 4, 7, 9, 2, 4, 1, 6, 7, 3}

Let's then use qsort to sort them. This operation is typically O(n*log n).

{1, 1, 2, 3, 4, 4, 6, 7, 7, 9}

Now, we can do a linear loop over these and find the unique elements. These are the ones present in one but not both of the arrays.

{2, 3, 6, 9}

But this doesn't tell us which is in the first array. That sounds like a nested loop issue. Instead, though, let's combine that with the first array.

{1, 4, 7, 9, 2, 2, 3, 6, 9}

And we'll sort this.

{1, 2, 2, 3, 4, 6, 7, 9, 9}

Now we'll scan for the first repeated number.

2

An implementation

Note: Does not check for malloc errors.

#include <stdio.h>
#include <stdlib.h>

int cmp(const void *a, const void *b) {
    int c = *(const int *)a;
    int d = *(const int *)b;

    if (c == d) return 0;
    else if (c < d) return -1;
    else return 1;
}

int min_not_in_2nd_array(int *result, int *arr1, size_t m, int *arr2, size_t n) {
    int *temp = malloc(sizeof(int) * (m + n));
    //if (!temp) return 0;

    for (size_t i = 0; i < m; ++i) temp[i] = arr1[i];
    for (size_t i = 0; i < n; ++i) temp[m+i] = arr2[i];

    qsort(temp, m+n, sizeof(int), cmp);

    int *uniques = malloc(sizeof(int) * (m + n));
    //if (!uniques) return 0;

    size_t n_uniques = 0;
    int cur = temp[0] - 1;
    size_t cur_count = 0;

    for (size_t i = 0; i < m+n; ++i) {
        if (i == m+n-1 && temp[i] != temp[i-1]) {
            uniques[n_uniques++] = temp[i]; 
        }
        else if (temp[i] != cur) {
            if (cur_count == 1) uniques[n_uniques++] = cur; 
            cur = temp[i];
            cur_count = 1;
        }
        else {
            cur_count++;    
        }
    }

    //for (size_t i = 0; i < n_uniques; ++i) printf("%d ", uniques[i]);
    //printf("\n");
    
    int *temp2 = malloc(sizeof(int) * (m + n_uniques));
    // if (!temp2) return 0;
    
    for (size_t i = 0; i < m; ++i) temp2[i] = arr1[i];
    for (size_t i = 0; i < n_uniques; ++i) temp2[m+i] = uniques[i];
    
    qsort(temp2, m+n_uniques, sizeof(int), cmp);
    
    int found = 0;
    
    for (size_t i = 0; i < m+n_uniques-1; ++i) {
        if (temp2[i] == temp2[i+1]) {
            *result = temp2[i];
            found = 1;
            break;
        }
    }

    free(temp);
    free(uniques);
    free(temp2);

    return found;
}

int main(void) {
    int foo[] = {1, 4, 7, 9, 2};
    int bar[] = {4, 1, 6, 7, 3};
    int baz;

    if (min_not_in_2nd_array(&baz, foo, sizeof(foo)/sizeof(*foo), 
                                   bar, sizeof(bar)/sizeof(*bar))) {
        printf("Min not in 2nd array is %d\n", baz);
    }
    else {
        printf("All elements shared.\n");
    }

    return 0;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.